blob: 3a79a9eb4b1daa9610bae5f679628ec82cd31e53 [file] [log] [blame]
wdenk7ac16102004-08-01 22:48:16 +00001/*
2 * (C) 2000-2004 Wolfgang Denk, DENX Software Engineering, wd@denx.de.
3 * (C) 2003 August Hoeraendl, Logotronic GmbH
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#undef CONFIG_FLASH_16BIT
25
26#include <common.h>
27
28#if defined CFG_JFFS_CUSTOM_PART
29#include <jffs2/jffs2.h>
30#endif
31
32#define FLASH_BANK_SIZE MX1FS2_FLASH_BANK_SIZE
33#define MAIN_SECT_SIZE MX1FS2_FLASH_SECT_SIZE
34
35flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
36
37/*
38 * NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
39 * has nothing to do with the flash chip being 8-bit or 16-bit.
40 */
41#ifdef CONFIG_FLASH_16BIT
42typedef unsigned short FLASH_PORT_WIDTH;
43typedef volatile unsigned short FLASH_PORT_WIDTHV;
44
45#define FLASH_ID_MASK 0xFFFF
46#else
47typedef unsigned long FLASH_PORT_WIDTH;
48typedef volatile unsigned long FLASH_PORT_WIDTHV;
49
50#define FLASH_ID_MASK 0xFFFFFFFF
51#endif
52
53#define FPW FLASH_PORT_WIDTH
54#define FPWV FLASH_PORT_WIDTHV
55
56#define ORMASK(size) ((-size) & OR_AM_MSK)
57
58/*-----------------------------------------------------------------------
59 * Functions
60 */
61#if 0
62static ulong flash_get_size(FPWV * addr, flash_info_t * info);
63static void flash_get_offsets(ulong base, flash_info_t * info);
64#endif
65static void flash_reset(flash_info_t * info);
66static int write_word_intel(flash_info_t * info, FPWV * dest, FPW data);
67static int write_word_amd(flash_info_t * info, FPWV * dest, FPW data);
68#define write_word(in, de, da) write_word_amd(in, de, da)
69#ifdef CFG_FLASH_PROTECTION
70static void flash_sync_real_protect(flash_info_t * info);
71#endif
72
73#if defined CFG_JFFS_CUSTOM_PART
74
75/**
76 * jffs2_part_info - get information about a JFFS2 partition
77 *
78 * @part_num: number of the partition you want to get info about
79 * @return: struct part_info* in case of success, 0 if failure
80 */
81
82static struct part_info part;
83static int current_part = -1;
84
85struct part_info *
86jffs2_part_info(int part_num)
87{
88 void *jffs2_priv_saved = part.jffs2_priv;
89
90 printf("jffs2_part_info: part_num=%i\n", part_num);
91
92 if (current_part == part_num)
93 return &part;
94
95 /* rootfs */
96 if (part_num == 0) {
97 memset(&part, 0, sizeof (part));
98
99 part.offset = (char *) MX1FS2_JFFS2_PART0_START;
100 part.size = MX1FS2_JFFS2_PART0_SIZE;
101
102 /* Mark the struct as ready */
103 current_part = part_num;
104
105 printf("part.offset = 0x%08x\n", (unsigned int) part.offset);
106 printf("part.size = 0x%08x\n", (unsigned int) part.size);
107 }
108
109 /* userfs */
110 if (part_num == 1) {
111 memset(&part, 0, sizeof (part));
112
113 part.offset = (char *) MX1FS2_JFFS2_PART1_START;
114 part.size = MX1FS2_JFFS2_PART1_SIZE;
115
116 /* Mark the struct as ready */
117 current_part = part_num;
118
119 printf("part.offset = 0x%08x\n", (unsigned int) part.offset);
120 printf("part.size = 0x%08x\n", (unsigned int) part.size);
121 }
122
123 if (current_part == part_num) {
124 part.usr_priv = &current_part;
125 part.jffs2_priv = jffs2_priv_saved;
126 return &part;
127 }
128
129 printf("jffs2_part_info: end of partition table\n");
130 return 0;
131}
132#endif /* CFG_JFFS_CUSTOM_PART */
133
134/*-----------------------------------------------------------------------
135 * flash_init()
136 *
137 * sets up flash_info and returns size of FLASH (bytes)
138 */
139ulong
140flash_init(void)
141{
142 int i, j;
143 ulong size = 0;
144
145 for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
146 ulong flashbase = 0;
147 flash_info[i].flash_id =
148 (FLASH_MAN_AMD & FLASH_VENDMASK) |
149 (FLASH_AM640U & FLASH_TYPEMASK);
150 flash_info[i].size = FLASH_BANK_SIZE;
151 flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
152 memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
153 switch (i) {
154 case 0:
155 flashbase = MX1FS2_FLASH_BASE;
156 break;
157 default:
158 panic("configured too many flash banks!\n");
159 break;
160 }
161 for (j = 0; j < flash_info[i].sector_count; j++) {
162 flash_info[i].start[j] = flashbase + j * MAIN_SECT_SIZE;
163 }
164 size += flash_info[i].size;
165 }
166
167 /* Protect monitor and environment sectors */
168 flash_protect(FLAG_PROTECT_SET,
169 CFG_FLASH_BASE,
170 CFG_FLASH_BASE + _bss_start - _armboot_start,
171 &flash_info[0]);
172
173 flash_protect(FLAG_PROTECT_SET,
174 CFG_ENV_ADDR,
175 CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
176
177 return size;
178}
179
180/*-----------------------------------------------------------------------
181 */
182static void
183flash_reset(flash_info_t * info)
184{
185 FPWV *base = (FPWV *) (info->start[0]);
186
187 /* Put FLASH back in read mode */
188 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
189 *base = (FPW) 0x00FF00FF; /* Intel Read Mode */
190 else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
191 *base = (FPW) 0x00F000F0; /* AMD Read Mode */
192}
193
194/*-----------------------------------------------------------------------
195 */
196#if 0
197static void
198flash_get_offsets(ulong base, flash_info_t * info)
199{
200 int i;
201
202 /* set up sector start address table */
203 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL
204 && (info->flash_id & FLASH_BTYPE)) {
205 int bootsect_size; /* number of bytes/boot sector */
206 int sect_size; /* number of bytes/regular sector */
207
208 bootsect_size = 0x00002000 * (sizeof (FPW) / 2);
209 sect_size = 0x00010000 * (sizeof (FPW) / 2);
210
211 /* set sector offsets for bottom boot block type */
212 for (i = 0; i < 8; ++i) {
213 info->start[i] = base + (i * bootsect_size);
214 }
215 for (i = 8; i < info->sector_count; i++) {
216 info->start[i] = base + ((i - 7) * sect_size);
217 }
218 } else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
219 && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U) {
220
221 int sect_size; /* number of bytes/sector */
222
223 sect_size = 0x00010000 * (sizeof (FPW) / 2);
224
225 /* set up sector start address table (uniform sector type) */
226 for (i = 0; i < info->sector_count; i++)
227 info->start[i] = base + (i * sect_size);
228 }
229}
230#endif /* 0 */
231
232/*-----------------------------------------------------------------------
233 */
234
235void
236flash_print_info(flash_info_t * info)
237{
238 int i;
239 uchar *boottype;
240 uchar *bootletter;
241 uchar *fmt;
242 uchar botbootletter[] = "B";
243 uchar topbootletter[] = "T";
244 uchar botboottype[] = "bottom boot sector";
245 uchar topboottype[] = "top boot sector";
246
247 if (info->flash_id == FLASH_UNKNOWN) {
248 printf("missing or unknown FLASH type\n");
249 return;
250 }
251
252 switch (info->flash_id & FLASH_VENDMASK) {
253 case FLASH_MAN_AMD:
254 printf("AMD ");
255 break;
256 case FLASH_MAN_BM:
257 printf("BRIGHT MICRO ");
258 break;
259 case FLASH_MAN_FUJ:
260 printf("FUJITSU ");
261 break;
262 case FLASH_MAN_SST:
263 printf("SST ");
264 break;
265 case FLASH_MAN_STM:
266 printf("STM ");
267 break;
268 case FLASH_MAN_INTEL:
269 printf("INTEL ");
270 break;
271 default:
272 printf("Unknown Vendor ");
273 break;
274 }
275
276 /* check for top or bottom boot, if it applies */
277 if (info->flash_id & FLASH_BTYPE) {
278 boottype = botboottype;
279 bootletter = botbootletter;
280 } else {
281 boottype = topboottype;
282 bootletter = topbootletter;
283 }
284
285 switch (info->flash_id & FLASH_TYPEMASK) {
286 case FLASH_AM640U:
287 fmt = "29LV641D (64 Mbit, uniform sectors)\n";
288 break;
289 case FLASH_28F800C3B:
290 case FLASH_28F800C3T:
291 fmt = "28F800C3%s (8 Mbit, %s)\n";
292 break;
293 case FLASH_INTEL800B:
294 case FLASH_INTEL800T:
295 fmt = "28F800B3%s (8 Mbit, %s)\n";
296 break;
297 case FLASH_28F160C3B:
298 case FLASH_28F160C3T:
299 fmt = "28F160C3%s (16 Mbit, %s)\n";
300 break;
301 case FLASH_INTEL160B:
302 case FLASH_INTEL160T:
303 fmt = "28F160B3%s (16 Mbit, %s)\n";
304 break;
305 case FLASH_28F320C3B:
306 case FLASH_28F320C3T:
307 fmt = "28F320C3%s (32 Mbit, %s)\n";
308 break;
309 case FLASH_INTEL320B:
310 case FLASH_INTEL320T:
311 fmt = "28F320B3%s (32 Mbit, %s)\n";
312 break;
313 case FLASH_28F640C3B:
314 case FLASH_28F640C3T:
315 fmt = "28F640C3%s (64 Mbit, %s)\n";
316 break;
317 case FLASH_INTEL640B:
318 case FLASH_INTEL640T:
319 fmt = "28F640B3%s (64 Mbit, %s)\n";
320 break;
321 default:
322 fmt = "Unknown Chip Type\n";
323 break;
324 }
325
326 printf(fmt, bootletter, boottype);
327
328 printf(" Size: %ld MB in %d Sectors\n",
329 info->size >> 20, info->sector_count);
330
331 printf(" Sector Start Addresses:");
332
333 for (i = 0; i < info->sector_count; ++i) {
334 if ((i % 5) == 0) {
335 printf("\n ");
336 }
337
338 printf(" %08lX%s", info->start[i],
339 info->protect[i] ? " (RO)" : " ");
340 }
341
342 printf("\n");
343}
344
345/*-----------------------------------------------------------------------
346 */
347
348/*
349 * The following code cannot be run from FLASH!
350 */
351
352#if 0
353ulong
354flash_get_size(FPWV * addr, flash_info_t * info)
355{
356 /* Write auto select command: read Manufacturer ID */
357
358 /* Write auto select command sequence and test FLASH answer */
359 addr[0x0555] = (FPW) 0x00AA00AA; /* for AMD, Intel ignores this */
360 addr[0x02AA] = (FPW) 0x00550055; /* for AMD, Intel ignores this */
361 addr[0x0555] = (FPW) 0x00900090; /* selects Intel or AMD */
362
363 /* The manufacturer codes are only 1 byte, so just use 1 byte.
364 * This works for any bus width and any FLASH device width.
365 */
366 switch (addr[0] & 0xff) {
367
368 case (uchar) AMD_MANUFACT:
369 info->flash_id = FLASH_MAN_AMD;
370 break;
371
372 case (uchar) INTEL_MANUFACT:
373 info->flash_id = FLASH_MAN_INTEL;
374 break;
375
376 default:
377 info->flash_id = FLASH_UNKNOWN;
378 info->sector_count = 0;
379 info->size = 0;
380 break;
381 }
382
383 /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
384 if (info->flash_id != FLASH_UNKNOWN)
385 switch (addr[1]) {
386
387 case (FPW) AMD_ID_LV640U: /* 29LV640 and 29LV641 have same ID */
388 info->flash_id += FLASH_AM640U;
389 info->sector_count = 128;
390 info->size = 0x00800000 * (sizeof (FPW) / 2);
391 break; /* => 8 or 16 MB */
392
393 case (FPW) INTEL_ID_28F800C3B:
394 info->flash_id += FLASH_28F800C3B;
395 info->sector_count = 23;
396 info->size = 0x00100000 * (sizeof (FPW) / 2);
397 break; /* => 1 or 2 MB */
398
399 case (FPW) INTEL_ID_28F800B3B:
400 info->flash_id += FLASH_INTEL800B;
401 info->sector_count = 23;
402 info->size = 0x00100000 * (sizeof (FPW) / 2);
403 break; /* => 1 or 2 MB */
404
405 case (FPW) INTEL_ID_28F160C3B:
406 info->flash_id += FLASH_28F160C3B;
407 info->sector_count = 39;
408 info->size = 0x00200000 * (sizeof (FPW) / 2);
409 break; /* => 2 or 4 MB */
410
411 case (FPW) INTEL_ID_28F160B3B:
412 info->flash_id += FLASH_INTEL160B;
413 info->sector_count = 39;
414 info->size = 0x00200000 * (sizeof (FPW) / 2);
415 break; /* => 2 or 4 MB */
416
417 case (FPW) INTEL_ID_28F320C3B:
418 info->flash_id += FLASH_28F320C3B;
419 info->sector_count = 71;
420 info->size = 0x00400000 * (sizeof (FPW) / 2);
421 break; /* => 4 or 8 MB */
422
423 case (FPW) INTEL_ID_28F320B3B:
424 info->flash_id += FLASH_INTEL320B;
425 info->sector_count = 71;
426 info->size = 0x00400000 * (sizeof (FPW) / 2);
427 break; /* => 4 or 8 MB */
428
429 case (FPW) INTEL_ID_28F640C3B:
430 info->flash_id += FLASH_28F640C3B;
431 info->sector_count = 135;
432 info->size = 0x00800000 * (sizeof (FPW) / 2);
433 break; /* => 8 or 16 MB */
434
435 case (FPW) INTEL_ID_28F640B3B:
436 info->flash_id += FLASH_INTEL640B;
437 info->sector_count = 135;
438 info->size = 0x00800000 * (sizeof (FPW) / 2);
439 break; /* => 8 or 16 MB */
440
441 default:
442 info->flash_id = FLASH_UNKNOWN;
443 info->sector_count = 0;
444 info->size = 0;
445 return (0); /* => no or unknown flash */
446 }
447
448 flash_get_offsets((ulong) addr, info);
449
450 /* Put FLASH back in read mode */
451 flash_reset(info);
452
453 return (info->size);
454}
455#endif /* 0 */
456
457#ifdef CFG_FLASH_PROTECTION
458/*-----------------------------------------------------------------------
459 */
460
461static void
462flash_sync_real_protect(flash_info_t * info)
463{
464 FPWV *addr = (FPWV *) (info->start[0]);
465 FPWV *sect;
466 int i;
467
468 switch (info->flash_id & FLASH_TYPEMASK) {
469 case FLASH_28F800C3B:
470 case FLASH_28F800C3T:
471 case FLASH_28F160C3B:
472 case FLASH_28F160C3T:
473 case FLASH_28F320C3B:
474 case FLASH_28F320C3T:
475 case FLASH_28F640C3B:
476 case FLASH_28F640C3T:
477 /* check for protected sectors */
478 *addr = (FPW) 0x00900090;
479 for (i = 0; i < info->sector_count; i++) {
480 /* read sector protection at sector address, (A7 .. A0) = 0x02.
481 * D0 = 1 for each device if protected.
482 * If at least one device is protected the sector is marked
483 * protected, but mixed protected and unprotected devices
484 * within a sector should never happen.
485 */
486 sect = (FPWV *) (info->start[i]);
487 info->protect[i] =
488 (sect[2] & (FPW) (0x00010001)) ? 1 : 0;
489 }
490
491 /* Put FLASH back in read mode */
492 flash_reset(info);
493 break;
494
495 case FLASH_AM640U:
496 default:
497 /* no hardware protect that we support */
498 break;
499 }
500}
501#endif
502
503/*-----------------------------------------------------------------------
504 */
505
506int
507flash_erase(flash_info_t * info, int s_first, int s_last)
508{
509 FPWV *addr;
510 int flag, prot, sect;
511 int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
512 ulong start, now, last;
513 int rcode = 0;
514
515 if ((s_first < 0) || (s_first > s_last)) {
516 if (info->flash_id == FLASH_UNKNOWN) {
517 printf("- missing\n");
518 } else {
519 printf("- no sectors to erase\n");
520 }
521 return 1;
522 }
523
524 switch (info->flash_id & FLASH_TYPEMASK) {
525 case FLASH_INTEL800B:
526 case FLASH_INTEL160B:
527 case FLASH_INTEL320B:
528 case FLASH_INTEL640B:
529 case FLASH_28F800C3B:
530 case FLASH_28F160C3B:
531 case FLASH_28F320C3B:
532 case FLASH_28F640C3B:
533 case FLASH_AM640U:
534 break;
535 case FLASH_UNKNOWN:
536 default:
537 printf("Can't erase unknown flash type %08lx - aborted\n",
538 info->flash_id);
539 return 1;
540 }
541
542 prot = 0;
543 for (sect = s_first; sect <= s_last; ++sect) {
544 if (info->protect[sect]) {
545 prot++;
546 }
547 }
548
549 if (prot) {
550 printf("- Warning: %d protected sectors will not be erased!\n",
551 prot);
552 } else {
553 printf("\n");
554 }
555
556 start = get_timer(0);
557 last = start;
558
559 /* Start erase on unprotected sectors */
560 for (sect = s_first; sect <= s_last && rcode == 0; sect++) {
561
562 if (info->protect[sect] != 0) /* protected, skip it */
563 continue;
564
565 /* Disable interrupts which might cause a timeout here */
566 flag = disable_interrupts();
567
568 addr = (FPWV *) (info->start[sect]);
569 if (intel) {
570 *addr = (FPW) 0x00500050; /* clear status register */
571 *addr = (FPW) 0x00200020; /* erase setup */
572 *addr = (FPW) 0x00D000D0; /* erase confirm */
573 } else {
574 /* must be AMD style if not Intel */
575 FPWV *base; /* first address in bank */
576
577 base = (FPWV *) (info->start[0]);
578 base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
579 base[0x02AA] = (FPW) 0x00550055; /* unlock */
580 base[0x0555] = (FPW) 0x00800080; /* erase mode */
581 base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
582 base[0x02AA] = (FPW) 0x00550055; /* unlock */
583 *addr = (FPW) 0x00300030; /* erase sector */
584 }
585
586 /* re-enable interrupts if necessary */
587 if (flag)
588 enable_interrupts();
589
590 /* wait at least 50us for AMD, 80us for Intel.
591 * Let's wait 1 ms.
592 */
593 udelay(1000);
594
595 while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
596 if ((now = get_timer(0)) - start > CFG_FLASH_ERASE_TOUT) {
597 printf("Timeout\n");
598
599 if (intel) {
600 /* suspend erase */
601 *addr = (FPW) 0x00B000B0;
602 }
603
604 flash_reset(info); /* reset to read mode */
605 rcode = 1; /* failed */
606 break;
607 }
608
609 /* show that we're waiting */
610 if ((now - last) > 1000) { /* every second */
611 putc('.');
612 last = now;
613 }
614 }
615
616 flash_reset(info); /* reset to read mode */
617 }
618
619 printf(" done\n");
620 return rcode;
621}
622
623/*-----------------------------------------------------------------------
624 * Copy memory to flash, returns:
625 * 0 - OK
626 * 1 - write timeout
627 * 2 - Flash not erased
628 */
629int
630bad_write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
631{
632 FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
633 int bytes; /* number of bytes to program in current word */
634 int left; /* number of bytes left to program */
635 int i, res;
636
637 for (left = cnt, res = 0;
638 left > 0 && res == 0;
639 addr += sizeof (data), left -= sizeof (data) - bytes) {
640
641 bytes = addr & (sizeof (data) - 1);
642 addr &= ~(sizeof (data) - 1);
643
644 /* combine source and destination data so can program
645 * an entire word of 16 or 32 bits
646 */
647 for (i = 0; i < sizeof (data); i++) {
648 data <<= 8;
649 if (i < bytes || i - bytes >= left)
650 data += *((uchar *) addr + i);
651 else
652 data += *src++;
653 }
654
655 /* write one word to the flash */
656 switch (info->flash_id & FLASH_VENDMASK) {
657 case FLASH_MAN_AMD:
658 res = write_word_amd(info, (FPWV *) addr, data);
659 break;
660 case FLASH_MAN_INTEL:
661 res = write_word_intel(info, (FPWV *) addr, data);
662 break;
663 default:
664 /* unknown flash type, error! */
665 printf("missing or unknown FLASH type\n");
666 res = 1; /* not really a timeout, but gives error */
667 break;
668 }
669 }
670
671 return (res);
672}
673
674/**
675 * write_buf: - Copy memory to flash.
676 *
677 * @param info:
678 * @param src: source of copy transaction
679 * @param addr: where to copy to
680 * @param cnt: number of bytes to copy
681 *
682 * @return error code
683 */
684
685int
686write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
687{
688 ulong cp, wp;
689 FPW data;
690 int l;
691 int i, rc;
692
693 wp = (addr & ~1); /* get lower word aligned address */
694
695 /* handle unaligned start bytes */
696 if ((l = addr - wp) != 0) {
697 data = 0;
698 for (i = 0, cp = wp; i < l; ++i, ++cp) {
699 data = (data >> 8) | (*(uchar *) cp << 8);
700 }
701 for (; i < 2 && cnt > 0; ++i) {
702 data = (data >> 8) | (*src++ << 8);
703 --cnt;
704 ++cp;
705 }
706 for (; cnt == 0 && i < 2; ++i, ++cp) {
707 data = (data >> 8) | (*(uchar *) cp << 8);
708 }
709
710 if ((rc = write_word(info, (FPWV *)wp, data)) != 0) {
711 return (rc);
712 }
713 wp += 2;
714 }
715
716 /* handle word aligned part */
717 while (cnt >= 2) {
718 /* data = *((vushort*)src); */
719 data = *((FPW *) src);
720 if ((rc = write_word(info, (FPWV *)wp, data)) != 0) {
721 return (rc);
722 }
723 src += sizeof (FPW);
724 wp += sizeof (FPW);
725 cnt -= sizeof (FPW);
726 }
727
728 if (cnt == 0)
729 return ERR_OK;
730
731 /*
732 * handle unaligned tail bytes
733 */
734 data = 0;
735 for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
736 data = (data >> 8) | (*src++ << 8);
737 --cnt;
738 }
739 for (; i < 2; ++i, ++cp) {
740 data = (data >> 8) | (*(uchar *) cp << 8);
741 }
742
743 return write_word(info, (FPWV *)wp, data);
744}
745
746/*-----------------------------------------------------------------------
747 * Write a word to Flash for AMD FLASH
748 * A word is 16 or 32 bits, whichever the bus width of the flash bank
749 * (not an individual chip) is.
750 *
751 * returns:
752 * 0 - OK
753 * 1 - write timeout
754 * 2 - Flash not erased
755 */
756static int
757write_word_amd(flash_info_t * info, FPWV * dest, FPW data)
758{
759 ulong start;
760 int flag;
761 int res = 0; /* result, assume success */
762 FPWV *base; /* first address in flash bank */
763
764 /* Check if Flash is (sufficiently) erased */
765 if ((*dest & data) != data) {
766 return (2);
767 }
768
769 base = (FPWV *) (info->start[0]);
770 /* Disable interrupts which might cause a timeout here */
771 flag = disable_interrupts();
772
773 base[0x0555] = (FPW) 0x00AA00AA; /* unlock */
774 base[0x02AA] = (FPW) 0x00550055; /* unlock */
775 base[0x0555] = (FPW) 0x00A000A0; /* selects program mode */
776
777 *dest = data; /* start programming the data */
778
779 /* re-enable interrupts if necessary */
780 if (flag)
781 enable_interrupts();
782
783 start = get_timer(0);
784
785 /* data polling for D7 */
786 while (res == 0
787 && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
788 if (get_timer(0) - start > CFG_FLASH_WRITE_TOUT) {
789 *dest = (FPW) 0x00F000F0; /* reset bank */
790 printf("SHA timeout\n");
791 res = 1;
792 }
793 }
794
795 return (res);
796}
797
798/*-----------------------------------------------------------------------
799 * Write a word to Flash for Intel FLASH
800 * A word is 16 or 32 bits, whichever the bus width of the flash bank
801 * (not an individual chip) is.
802 *
803 * returns:
804 * 0 - OK
805 * 1 - write timeout
806 * 2 - Flash not erased
807 */
808static int
809write_word_intel(flash_info_t * info, FPWV * dest, FPW data)
810{
811 ulong start;
812 int flag;
813 int res = 0; /* result, assume success */
814
815 /* Check if Flash is (sufficiently) erased */
816 if ((*dest & data) != data) {
817 return (2);
818 }
819
820 /* Disable interrupts which might cause a timeout here */
821 flag = disable_interrupts();
822
823 *dest = (FPW) 0x00500050; /* clear status register */
824 *dest = (FPW) 0x00FF00FF; /* make sure in read mode */
825 *dest = (FPW) 0x00400040; /* program setup */
826
827 *dest = data; /* start programming the data */
828
829 /* re-enable interrupts if necessary */
830 if (flag)
831 enable_interrupts();
832
833 start = get_timer(0);
834
835 while (res == 0 && (*dest & (FPW) 0x00800080) != (FPW) 0x00800080) {
836 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
837 *dest = (FPW) 0x00B000B0; /* Suspend program */
838 res = 1;
839 }
840 }
841
842 if (res == 0 && (*dest & (FPW) 0x00100010))
843 res = 1; /* write failed, time out error is close enough */
844
845 *dest = (FPW) 0x00500050; /* clear status register */
846 *dest = (FPW) 0x00FF00FF; /* make sure in read mode */
847
848 return (res);
849}
850
851#ifdef CFG_FLASH_PROTECTION
852/*-----------------------------------------------------------------------
853 */
854int
855flash_real_protect(flash_info_t * info, long sector, int prot)
856{
857 int rcode = 0; /* assume success */
858 FPWV *addr; /* address of sector */
859 FPW value;
860
861 addr = (FPWV *) (info->start[sector]);
862
863 switch (info->flash_id & FLASH_TYPEMASK) {
864 case FLASH_28F800C3B:
865 case FLASH_28F800C3T:
866 case FLASH_28F160C3B:
867 case FLASH_28F160C3T:
868 case FLASH_28F320C3B:
869 case FLASH_28F320C3T:
870 case FLASH_28F640C3B:
871 case FLASH_28F640C3T:
872 flash_reset(info); /* make sure in read mode */
873 *addr = (FPW) 0x00600060L; /* lock command setup */
874 if (prot)
875 *addr = (FPW) 0x00010001L; /* lock sector */
876 else
877 *addr = (FPW) 0x00D000D0L; /* unlock sector */
878 flash_reset(info); /* reset to read mode */
879
880 /* now see if it really is locked/unlocked as requested */
881 *addr = (FPW) 0x00900090;
882 /* read sector protection at sector address, (A7 .. A0) = 0x02.
883 * D0 = 1 for each device if protected.
884 * If at least one device is protected the sector is marked
885 * protected, but return failure. Mixed protected and
886 * unprotected devices within a sector should never happen.
887 */
888 value = addr[2] & (FPW) 0x00010001;
889 if (value == 0)
890 info->protect[sector] = 0;
891 else if (value == (FPW) 0x00010001)
892 info->protect[sector] = 1;
893 else {
894 /* error, mixed protected and unprotected */
895 rcode = 1;
896 info->protect[sector] = 1;
897 }
898 if (info->protect[sector] != prot)
899 rcode = 1; /* failed to protect/unprotect as requested */
900
901 /* reload all protection bits from hardware for now */
902 flash_sync_real_protect(info);
903 break;
904
905 case FLASH_AM640U:
906 default:
907 /* no hardware protect that we support */
908 info->protect[sector] = prot;
909 break;
910 }
911
912 return rcode;
913}
914#endif