blob: 21eae0e949068ddae43a50e37c519efc09303959 [file] [log] [blame]
wdenk5da7f2f2004-01-03 00:43:19 +00001/*
2 * (C) Copyright 2001
3 * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
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/*
25 * flash.c - flash support for the 512k, 8bit boot flash
Wolfgang Denka1be4762008-05-20 16:00:29 +020026 and the 8MB 32bit extra flash on the DB64360
wdenk5da7f2f2004-01-03 00:43:19 +000027 * most of this file was based on the existing U-Boot
28 * flash drivers.
29 *
30 * written or collected and sometimes rewritten by
31 * Ingo Assmus <ingo.assmus@keymile.com>
32 *
33 */
34
35#include <common.h>
36#include <mpc8xx.h>
37#include "../include/mv_gen_reg.h"
38#include "../include/memory.h"
39#include "intel_flash.h"
40
41#define FLASH_ROM 0xFFFD /* unknown flash type */
42#define FLASH_RAM 0xFFFE /* unknown flash type */
43#define FLASH_MAN_UNKNOWN 0xFFFF0000
44
45/* #define DEBUG */
46
47/* Intel flash commands */
48int flash_erase_intel (flash_info_t * info, int s_first, int s_last);
49int write_word_intel (bank_addr_t addr, bank_word_t value);
50
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020051flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
wdenk5da7f2f2004-01-03 00:43:19 +000052
53/*-----------------------------------------------------------------------
54 * Functions
55 */
56static ulong flash_get_size (int portwidth, vu_long * addr,
57 flash_info_t * info);
58static int write_word (flash_info_t * info, ulong dest, ulong data);
59static void flash_get_offsets (ulong base, flash_info_t * info);
60
61/*-----------------------------------------------------------------------
62 */
63
64unsigned long flash_init (void)
65{
66 unsigned int i;
67 unsigned long size_b0 = 0, size_b1 = 0;
68 unsigned long base, flash_size;
69
70 /* Init: no FLASHes known */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020071 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
wdenk5da7f2f2004-01-03 00:43:19 +000072 flash_info[i].flash_id = FLASH_UNKNOWN;
73 }
74
75 /* the boot flash */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020076 base = CONFIG_SYS_FLASH_BASE;
wdenk5da7f2f2004-01-03 00:43:19 +000077 size_b0 =
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020078 flash_get_size (CONFIG_SYS_BOOT_FLASH_WIDTH, (vu_long *) base,
wdenk5da7f2f2004-01-03 00:43:19 +000079 &flash_info[0]);
80
81 printf ("[%ldkB@%lx] ", size_b0 / 1024, base);
82
83 if (flash_info[0].flash_id == FLASH_UNKNOWN) {
84 printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n", base, size_b0, size_b0 << 20);
85 }
86
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020087 base = memoryGetDeviceBaseAddress (CONFIG_SYS_EXTRA_FLASH_DEVICE);
wdenk5da7f2f2004-01-03 00:43:19 +000088/* base = memoryGetDeviceBaseAddress(DEV_CS3_BASE_ADDR);*/
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020089 for (i = 1; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
wdenk5da7f2f2004-01-03 00:43:19 +000090 unsigned long size =
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020091 flash_get_size (CONFIG_SYS_EXTRA_FLASH_WIDTH,
wdenk5da7f2f2004-01-03 00:43:19 +000092 (vu_long *) base, &flash_info[i]);
93
94 printf ("[%ldMB@%lx] ", size >> 20, base);
95
96 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
97 if (i == 1) {
98 printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n", base, size_b1, size_b1 << 20);
99 }
100 break;
101 }
102 size_b1 += size;
103 base += size;
104 }
105
106 flash_size = size_b0 + size_b1;
107 return flash_size;
108}
109
110/*-----------------------------------------------------------------------
111 */
112static void flash_get_offsets (ulong base, flash_info_t * info)
113{
114 int i;
115 int sector_size;
116
117 if (!info->sector_count)
118 return;
119
120 /* set up sector start address table */
121 switch (info->flash_id & FLASH_TYPEMASK) {
122 case FLASH_AM040:
123 case FLASH_28F128J3A:
124 case FLASH_28F640J3A:
125 case FLASH_RAM:
126 /* this chip has uniformly spaced sectors */
127 sector_size = info->size / info->sector_count;
128 for (i = 0; i < info->sector_count; i++)
129 info->start[i] = base + (i * sector_size);
130 break;
131 default:
132 if (info->flash_id & FLASH_BTYPE) {
133 /* set sector offsets for bottom boot block type */
134 info->start[0] = base + 0x00000000;
135 info->start[1] = base + 0x00008000;
136 info->start[2] = base + 0x0000C000;
137 info->start[3] = base + 0x00010000;
138 for (i = 4; i < info->sector_count; i++) {
139 info->start[i] =
140 base + (i * 0x00020000) - 0x00060000;
141 }
142 } else {
143 /* set sector offsets for top boot block type */
144 i = info->sector_count - 1;
145 info->start[i--] = base + info->size - 0x00008000;
146 info->start[i--] = base + info->size - 0x0000C000;
147 info->start[i--] = base + info->size - 0x00010000;
148 for (; i >= 0; i--) {
149 info->start[i] = base + i * 0x00020000;
150 }
151 }
152 }
153}
154
155/*-----------------------------------------------------------------------
156 */
157void flash_print_info (flash_info_t * info)
158{
159 int i;
160
161 if (info->flash_id == FLASH_UNKNOWN) {
162 printf ("missing or unknown FLASH type\n");
163 return;
164 }
165
166 switch (info->flash_id & FLASH_VENDMASK) {
167 case FLASH_MAN_STM:
168 printf ("STM ");
169 break;
170 case FLASH_MAN_AMD:
171 printf ("AMD ");
172 break;
173 case FLASH_MAN_FUJ:
174 printf ("FUJITSU ");
175 break;
176 case FLASH_MAN_INTEL:
177 printf ("INTEL ");
178 break;
179 default:
180 printf ("Unknown Vendor ");
181 break;
182 }
183
184 switch (info->flash_id & FLASH_TYPEMASK) {
185 case FLASH_AM040:
186 printf ("AM29LV040B (4 Mbit, bottom boot sect)\n");
187 break;
188 case FLASH_AM400B:
189 printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
190 break;
191 case FLASH_AM400T:
192 printf ("AM29LV400T (4 Mbit, top boot sector)\n");
193 break;
194 case FLASH_AM800B:
195 printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
196 break;
197 case FLASH_AM800T:
198 printf ("AM29LV800T (8 Mbit, top boot sector)\n");
199 break;
200 case FLASH_AM160B:
201 printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
202 break;
203 case FLASH_AM160T:
204 printf ("AM29LV160T (16 Mbit, top boot sector)\n");
205 break;
206 case FLASH_AM320B:
207 printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
208 break;
209 case FLASH_AM320T:
210 printf ("AM29LV320T (32 Mbit, top boot sector)\n");
211 break;
212 case FLASH_28F640J3A:
213 printf ("28F640J3A (64 Mbit)\n");
214 break;
215 case FLASH_28F128J3A:
216 printf ("28F128J3A (128 Mbit)\n");
217 break;
218 case FLASH_ROM:
219 printf ("ROM\n");
220 break;
221 case FLASH_RAM:
222 printf ("RAM\n");
223 break;
224 default:
225 printf ("Unknown Chip Type\n");
226 break;
227 }
228
229 if ((info->size >> 20) > 0) {
230 printf (" Size: %ld MB in %d Sectors\n",
231 info->size >> 20, info->sector_count);
232 } else {
233 printf (" Size: %ld kB in %d Sectors\n",
234 info->size >> 10, info->sector_count);
235 }
236
237 printf (" Sector Start Addresses:");
238 for (i = 0; i < info->sector_count; ++i) {
239 if ((i % 5) == 0)
240 printf ("\n ");
241 printf (" %08lX%s",
242 info->start[i], info->protect[i] ? " (RO)" : " ");
243 }
244 printf ("\n");
245 return;
246}
247
248/*-----------------------------------------------------------------------
249 */
250
251
252/*-----------------------------------------------------------------------
253 */
254
255/*
256 * The following code cannot be run from FLASH!
257 */
258
259static inline void flash_cmd (int width, volatile unsigned char *addr,
260 int offset, unsigned char cmd)
261{
262 /* supports 1x8, 1x16, and 2x16 */
263 /* 2x8 and 4x8 are not supported */
264 if (width == 4) {
265 /* assuming chips are in 16 bit mode */
266 /* 2x16 */
267 unsigned long cmd32 = (cmd << 16) | cmd;
268
269 *(volatile unsigned long *) (addr + offset * 2) = cmd32;
270 } else {
271 /* 1x16 or 1x8 */
272 *(volatile unsigned char *) (addr + offset) = cmd;
273 }
274}
275
276static ulong
277flash_get_size (int portwidth, vu_long * addr, flash_info_t * info)
278{
279 short i;
280 volatile unsigned char *caddr = (unsigned char *) addr;
281 volatile unsigned short *saddr = (unsigned short *) addr;
282 volatile unsigned long *laddr = (unsigned long *) addr;
283 char old[2], save;
284 ulong id = 0, manu = 0, base = (ulong) addr;
285
286#ifdef DEBUG
287 printf ("%s: enter\n", __FUNCTION__);
288#endif
289 info->portwidth = portwidth;
290
291 save = *caddr;
292
293 flash_cmd (portwidth, caddr, 0, 0xf0);
294 flash_cmd (portwidth, caddr, 0, 0xf0);
295
296 udelay (10);
297
298 old[0] = caddr[0];
299 old[1] = caddr[1];
300
301
302 if (old[0] != 0xf0) {
303 flash_cmd (portwidth, caddr, 0, 0xf0);
304 flash_cmd (portwidth, caddr, 0, 0xf0);
305
306 udelay (10);
307
308 if (*caddr == 0xf0) {
309 /* this area is ROM */
310 *caddr = save;
311 info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN;
312 info->sector_count = 8;
313 info->size = 0x80000;
314 flash_get_offsets (base, info);
315 return info->size;
316 }
317 } else {
318 *caddr = 0;
319
320 udelay (10);
321
322 if (*caddr == 0) {
323 /* this area is RAM */
324 *caddr = save;
325 info->flash_id = FLASH_RAM + FLASH_MAN_UNKNOWN;
326 info->sector_count = 8;
327 info->size = 0x80000;
328 flash_get_offsets (base, info);
329 return info->size;
330 }
331 flash_cmd (portwidth, caddr, 0, 0xf0);
332
333 udelay (10);
334 }
335
336 /* Write auto select command: read Manufacturer ID */
337 flash_cmd (portwidth, caddr, 0x555, 0xAA);
338 flash_cmd (portwidth, caddr, 0x2AA, 0x55);
339 flash_cmd (portwidth, caddr, 0x555, 0x90);
340
341 udelay (10);
342
343 if ((caddr[0] == old[0]) && (caddr[1] == old[1])) {
344
345 /* this area is ROM */
346 info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN;
347 info->sector_count = 8;
348 info->size = 0x80000;
349 flash_get_offsets (base, info);
350 return info->size;
351#ifdef DEBUG
352 } else {
353 printf ("%px%d: %02x:%02x -> %02x:%02x\n",
354 caddr, portwidth, old[0], old[1], caddr[0], caddr[1]);
355#endif
356 }
357
358 switch (portwidth) {
359 case 1:
360 manu = caddr[0];
361 manu |= manu << 16;
362 id = caddr[1];
363 break;
364 case 2:
365 manu = saddr[0];
366 manu |= manu << 16;
367 id = saddr[1];
368 id |= id << 16;
369 break;
370 case 4:
371 manu = laddr[0];
372 id = laddr[1];
373 break;
374 }
375
376#ifdef DEBUG
377 flash_cmd (portwidth, caddr, 0, 0xf0);
378
379 printf ("\n%08lx:%08lx:%08lx\n", base, manu, id);
380 printf ("%08lx %08lx %08lx %08lx\n",
381 laddr[0], laddr[1], laddr[2], laddr[3]);
382#endif
383
384 switch (manu) {
385 case STM_MANUFACT:
386 info->flash_id = FLASH_MAN_STM;
387 break;
388 case AMD_MANUFACT:
389 info->flash_id = FLASH_MAN_AMD;
390 break;
391 case FUJ_MANUFACT:
392 info->flash_id = FLASH_MAN_FUJ;
393 break;
394 case INTEL_MANUFACT:
395 info->flash_id = FLASH_MAN_INTEL;
396 break;
397 default:
398 flash_cmd (portwidth, caddr, 0, 0xf0);
399
400 printf ("Unknown Mfr [%08lx]:%08lx\n", manu, id);
401 info->flash_id = FLASH_UNKNOWN;
402 info->sector_count = 0;
403 info->size = 0;
404 return (0); /* no or unknown flash */
405 }
406
407 switch (id) {
408 case AMD_ID_LV400T:
409 info->flash_id += FLASH_AM400T;
410 info->sector_count = 11;
411 info->size = 0x00100000;
412 info->chipwidth = 1;
413 break; /* => 1 MB */
414
415 case AMD_ID_LV400B:
416 info->flash_id += FLASH_AM400B;
417 info->sector_count = 11;
418 info->size = 0x00100000;
419 info->chipwidth = 1;
420 break; /* => 1 MB */
421
422 case AMD_ID_LV800T:
423 info->flash_id += FLASH_AM800T;
424 info->sector_count = 19;
425 info->size = 0x00200000;
426 info->chipwidth = 1;
427 break; /* => 2 MB */
428
429 case AMD_ID_LV800B:
430 info->flash_id += FLASH_AM800B;
431 info->sector_count = 19;
432 info->size = 0x00200000;
433 info->chipwidth = 1;
434 break; /* => 2 MB */
435
436 case AMD_ID_LV160T:
437 info->flash_id += FLASH_AM160T;
438 info->sector_count = 35;
439 info->size = 0x00400000;
440 info->chipwidth = 1;
441 break; /* => 4 MB */
442
443 case AMD_ID_LV160B:
444 info->flash_id += FLASH_AM160B;
445 info->sector_count = 35;
446 info->size = 0x00400000;
447 info->chipwidth = 1;
448 break; /* => 4 MB */
449#if 0 /* enable when device IDs are available */
450 case AMD_ID_LV320T:
451 info->flash_id += FLASH_AM320T;
452 info->sector_count = 67;
453 info->size = 0x00800000;
454 break; /* => 8 MB */
455
456 case AMD_ID_LV320B:
457 info->flash_id += FLASH_AM320B;
458 info->sector_count = 67;
459 info->size = 0x00800000;
460 break; /* => 8 MB */
461#endif
462 case AMD_ID_LV040B:
463 info->flash_id += FLASH_AM040;
464 info->sector_count = 8;
465 info->size = 0x80000;
466 info->chipwidth = 1;
467 break; /* => 512 kB */
468
469 case INTEL_ID_28F640J3A:
470 info->flash_id += FLASH_28F640J3A;
471 info->sector_count = 64;
472 info->size = 128 * 1024 * 64; /* 128kbytes x 64 blocks */
473 info->chipwidth = 2;
474 if (portwidth == 4)
475 info->size *= 2; /* 2x16 */
476 break;
477
478 case INTEL_ID_28F128J3A:
479 info->flash_id += FLASH_28F128J3A;
480 info->sector_count = 128;
481 info->size = 128 * 1024 * 128; /* 128kbytes x 128 blocks */
482 info->chipwidth = 2;
483 if (portwidth == 4)
484 info->size *= 2; /* 2x16 */
485 break;
486
487 default:
488 flash_cmd (portwidth, caddr, 0, 0xf0);
489
490 printf ("Unknown id %lx:[%lx]\n", manu, id);
491 info->flash_id = FLASH_UNKNOWN;
492 info->chipwidth = 1;
493 return (0); /* => no or unknown flash */
494
495 }
496
497 flash_get_offsets (base, info);
498
499
500 /* check for protected sectors */
501 for (i = 0; i < info->sector_count; i++) {
502 /* read sector protection at sector address, (A7 .. A0)=0x02 */
503 /* D0 = 1 if protected */
504 caddr = (volatile unsigned char *) (info->start[i]);
505 saddr = (volatile unsigned short *) (info->start[i]);
506 laddr = (volatile unsigned long *) (info->start[i]);
507 if (portwidth == 1)
508 info->protect[i] = caddr[2] & 1;
509 else if (portwidth == 2)
510 info->protect[i] = saddr[2] & 1;
511 else
512 info->protect[i] = laddr[2] & 1;
513 }
514
515 /*
516 * Prevent writes to uninitialized FLASH.
517 */
518 if (info->flash_id != FLASH_UNKNOWN) {
519 caddr = (volatile unsigned char *) info->start[0];
520
521 flash_cmd (portwidth, caddr, 0, 0xF0); /* reset bank */
522 }
523
524 return (info->size);
525}
526
527int flash_erase (flash_info_t * info, int s_first, int s_last)
528{
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200529 volatile unsigned char *addr = (uchar *) (info->start[0]);
wdenk5da7f2f2004-01-03 00:43:19 +0000530 int flag, prot, sect, l_sect;
531 ulong start, now, last;
532
533/* modified to support 2x16 Intel flash */
534/* Note that the code will not exit on a flash erasure error or timeout */
535/* but will print and error message and continue processing sectors */
536/* until they are all erased. */
537/* 10-16-2002 P. Marchese */
538 ulong mask;
539 int timeout;
540
541 if (info->portwidth == 4)
542/* {
543 printf ("- Warning: erasing of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");
544 return 1;
545 }*/
546 {
547 /* make sure it's Intel flash */
548 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
549 /* yup! it's an Intel flash */
550 /* is it 16-bits wide? */
551 if (info->chipwidth == 2) {
552 /* yup! it's 16-bits wide */
553 /* are there any sectors to process? */
554 if ((s_first < 0) || (s_first > s_last)) {
555 printf ("Error: There are no sectors to erase\n");
556 printf ("Either sector %d is less than zero\n", s_first);
557 printf ("or sector %d is greater than sector %d\n", s_first, s_last);
558 return 1;
559 }
560 /* check for protected sectors */
561 prot = 0;
562 for (sect = s_first; sect <= s_last; ++sect)
563 if (info->protect[sect])
564 prot++;
565 /* if variable "prot" is nonzero, there are protected sectors */
566 if (prot)
567 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
568 /* reset the flash */
569 flash_cmd (info->portwidth, addr, 0,
570 CHIP_CMD_RST);
571 /* Disable interrupts which might cause a timeout here */
572 flag = disable_interrupts ();
573 /* Clear the status register */
574 flash_cmd (info->portwidth, addr, 0,
575 CHIP_CMD_CLR_STAT);
576 flash_cmd (info->portwidth, addr, 0,
577 CHIP_CMD_RST);
578 /* Start erase on unprotected sectors */
579 for (sect = s_first; sect <= s_last; sect++) {
580 /* is the sector unprotected? */
581 if (info->protect[sect] == 0) { /* not protected */
582 /* issue the single block erase command, 0x20 */
583 flash_cmd (info->portwidth,
584 (volatile unsigned
585 char *) info->
586 start[sect], 0,
587 CHIP_CMD_ERASE1);
588 /* issue the erase confirm command, 0xD0 */
589 flash_cmd (info->portwidth,
590 (volatile unsigned
591 char *) info->
592 start[sect], 0,
593 CHIP_CMD_ERASE2);
594 l_sect = sect;
595 /* re-enable interrupts if necessary */
596 if (flag)
597 enable_interrupts ();
598 /* poll for erasure completion */
599 /* put flash into read status mode by writing 0x70 to it */
600 flash_cmd (info->portwidth,
601 addr, 0,
602 CHIP_CMD_RD_STAT);
603 /* setup the status register mask */
604 mask = CHIP_STAT_RDY |
605 (CHIP_STAT_RDY << 16);
606 /* init. the timeout counter */
607 start = get_timer (0);
608 /* keep looping while the flash is not ready */
609 /* exit the loop by timing out or the flash */
610 /* becomes ready again */
611 timeout = 0;
612 while ((*
613 (volatile unsigned
614 long *) info->
615 start[sect] & mask) !=
616 mask) {
617 /* has the timeout limit been reached? */
618 if (get_timer (start)
619 >
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200620 CONFIG_SYS_FLASH_ERASE_TOUT)
wdenk5da7f2f2004-01-03 00:43:19 +0000621 {
622 /* timeout limit reached */
623 printf ("Time out limit reached erasing sector at address %08lx\n", info->start[sect]);
624 printf ("Continuing with next sector\n");
625 timeout = 1;
626 goto timed_out_error;
627 }
628 /* put flash into read status mode by writing 0x70 to it */
629 flash_cmd (info->
630 portwidth,
631 addr, 0,
632 CHIP_CMD_RD_STAT);
633 }
634 /* did we timeout? */
635 timed_out_error:if (timeout == 0)
636 {
637 /* didn't timeout, so check the status register */
638 /* create the status mask to check for errors */
639 mask = CHIP_STAT_ECLBS;
640 mask = mask | (mask <<
641 16);
642 /* put flash into read status mode by writing 0x70 to it */
643 flash_cmd (info->
644 portwidth,
645 addr, 0,
646 CHIP_CMD_RD_STAT);
647 /* are there any errors? */
648 if ((*
649 (volatile
650 unsigned long *)
651 info->
652 start[sect] &
653 mask) != 0) {
654 /* We got an erasure error */
655 printf ("Flash erasure error at address 0x%08lx\n", info->start[sect]);
656 printf ("Continuing with next sector\n");
657 /* reset the flash */
658 flash_cmd
659 (info->
660 portwidth,
661 addr,
662 0,
663 CHIP_CMD_RST);
664 }
665 }
666 /* erasure completed without errors */
667 /* reset the flash */
668 flash_cmd (info->portwidth,
669 addr, 0,
670 CHIP_CMD_RST);
671 } /* end if not protected */
672 } /* end for loop */
673 printf ("Flash erasure done\n");
674 return 0;
675 } else {
676 /* The Intel flash is not 16-bit wide */
677 /* print and error message and return */
678 /* NOTE: you can add routines here to handle other size flash */
679 printf ("Error: Intel flash device is only %d-bits wide\n", info->chipwidth * 8);
680 printf ("The erasure code only handles Intel 16-bit wide flash memory\n");
681 return 1;
682 }
683 } else {
684 /* Not Intel flash so return an error as a write timeout */
685 /* NOTE: if it's another type flash, stick its routine here */
686 printf ("Error: The flash device is not Intel type\n");
687 printf ("The erasure code only supports Intel flash in a 32-bit port width\n");
688 return 1;
689 }
690 }
691
692 /* end 32-bit wide flash code */
693 if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)
694 return 1; /* Rom can not be erased */
695 if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) { /* RAM just copy 0s to RAM */
696 for (sect = s_first; sect <= s_last; sect++) {
697 int sector_size = info->size / info->sector_count;
698
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200699 addr = (uchar *) (info->start[sect]);
wdenk5da7f2f2004-01-03 00:43:19 +0000700 memset ((void *) addr, 0, sector_size);
701 }
702 return 0;
703 }
704
705 if ((s_first < 0) || (s_first > s_last)) {
706 if (info->flash_id == FLASH_UNKNOWN) {
707 printf ("- missing\n");
708 } else {
709 printf ("- no sectors to erase\n");
710 }
711 return 1;
712 }
713
714 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { /* Intel works spezial */
715 return flash_erase_intel (info,
716 (unsigned short) s_first,
717 (unsigned short) s_last);
718 }
719#if 0
720 if ((info->flash_id == FLASH_UNKNOWN) || /* Flash is unknown to PPCBoot */
721 (info->flash_id > FLASH_AMD_COMP)) {
722 printf ("Can't erase unknown flash type %08lx - aborted\n",
723 info->flash_id);
724 return 1;
725 }
726#endif
727
728 prot = 0;
729 for (sect = s_first; sect <= s_last; ++sect) {
730 if (info->protect[sect]) {
731 prot++;
732 }
733 }
734
735 if (prot) {
736 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
737 } else {
738 printf ("\n");
739 }
740
741 l_sect = -1;
742
743 /* Disable interrupts which might cause a timeout here */
744 flag = disable_interrupts ();
745
746 flash_cmd (info->portwidth, addr, 0x555, 0xAA); /* start erase routine */
747 flash_cmd (info->portwidth, addr, 0x2AA, 0x55);
748 flash_cmd (info->portwidth, addr, 0x555, 0x80);
749 flash_cmd (info->portwidth, addr, 0x555, 0xAA);
750 flash_cmd (info->portwidth, addr, 0x2AA, 0x55);
751
752 /* Start erase on unprotected sectors */
753 for (sect = s_first; sect <= s_last; sect++) {
754 if (info->protect[sect] == 0) { /* not protected */
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200755 addr = (uchar *) (info->start[sect]);
wdenk5da7f2f2004-01-03 00:43:19 +0000756 flash_cmd (info->portwidth, addr, 0, 0x30);
757 l_sect = sect;
758 }
759 }
760
761 /* re-enable interrupts if necessary */
762 if (flag)
763 enable_interrupts ();
764
765 /* wait at least 80us - let's wait 1 ms */
766 udelay (1000);
767
768 /*
769 * We wait for the last triggered sector
770 */
771 if (l_sect < 0)
772 goto DONE;
773
774 start = get_timer (0);
775 last = start;
776 addr = (volatile unsigned char *) (info->start[l_sect]);
777 /* broken for 2x16: TODO */
778 while ((addr[0] & 0x80) != 0x80) {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200779 if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
wdenk5da7f2f2004-01-03 00:43:19 +0000780 printf ("Timeout\n");
781 return 1;
782 }
783 /* show that we're waiting */
784 if ((now - last) > 1000) { /* every second */
785 putc ('.');
786 last = now;
787 }
788 }
789
790 DONE:
791 /* reset to read mode */
792 addr = (volatile unsigned char *) info->start[0];
793 flash_cmd (info->portwidth, addr, 0, 0xf0);
794 flash_cmd (info->portwidth, addr, 0, 0xf0);
795
796 printf (" done\n");
797 return 0;
798}
799
800/*-----------------------------------------------------------------------
801 * Copy memory to flash, returns:
802 * 0 - OK
803 * 1 - write timeout
804 * 2 - Flash not erased
805 */
806
807/* broken for 2x16: TODO */
808int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
809{
810 ulong cp, wp, data;
811 int i, l, rc;
812
813/* Commented out since the below code should work for 32-bit(2x 16 flash) */
814/* 10-16-2002 P. Marchese */
815/* if(info->portwidth==4) return 1; */
816/* if(info->portwidth==4) {
817 printf ("- Warning: writting of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");
818 return 1;
819 }*/
820
821 if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)
822 return 0;
823 if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
824 memcpy ((void *) addr, src, cnt);
825 return 0;
826 }
827
828 wp = (addr & ~3); /* get lower word aligned address */
829
830 /*
831 * handle unaligned start bytes
832 */
833 if ((l = addr - wp) != 0) {
834 data = 0;
835 for (i = 0, cp = wp; i < l; ++i, ++cp) {
836 data = (data << 8) | (*(uchar *) cp);
837 }
838 for (; i < 4 && cnt > 0; ++i) {
839 data = (data << 8) | *src++;
840 --cnt;
841 ++cp;
842 }
843 for (; cnt == 0 && i < 4; ++i, ++cp) {
844 data = (data << 8) | (*(uchar *) cp);
845 }
846
847 if ((rc = write_word (info, wp, data)) != 0) {
848 return (rc);
849 }
850 wp += 4;
851 }
852
853 /*
854 * handle word aligned part
855 */
856 while (cnt >= 4) {
857 data = 0;
858 for (i = 0; i < 4; ++i) {
859 data = (data << 8) | *src++;
860 }
861 if ((rc = write_word (info, wp, data)) != 0) {
862 return (rc);
863 }
864 wp += 4;
865 cnt -= 4;
866 }
867
868 if (cnt == 0) {
869 return (0);
870 }
871
872 /*
873 * handle unaligned tail bytes
874 */
875 data = 0;
876 for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
877 data = (data << 8) | *src++;
878 --cnt;
879 }
880 for (; i < 4; ++i, ++cp) {
881 data = (data << 8) | (*(uchar *) cp);
882 }
883
884 return (write_word (info, wp, data));
885}
886
887/*-----------------------------------------------------------------------
888 * Write a word to Flash, returns:
889 * 0 - OK
890 * 1 - write timeout
891 * 2 - Flash not erased
892 */
893/* broken for 2x16: TODO */
894static int write_word (flash_info_t * info, ulong dest, ulong data)
895{
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200896 volatile unsigned char *addr = (uchar *) (info->start[0]);
wdenk5da7f2f2004-01-03 00:43:19 +0000897 ulong start;
898 int flag, i;
899 ulong mask;
900
901/* modified so that it handles 32-bit(2x16 Intel flash programming */
902/* 10-16-2002 P. Marchese */
903
904 if (info->portwidth == 4)
905/* {
906 printf ("- Warning: writting of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");
907 return 1;
908 }*/
909 {
910 /* make sure it's Intel flash */
911 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
912 /* yup! it's an Intel flash */
913 /* is it 16-bits wide? */
914 if (info->chipwidth == 2) {
915 /* yup! it's 16-bits wide */
916 /* so we know how to program it */
917 /* reset the flash */
918 flash_cmd (info->portwidth, addr, 0,
919 CHIP_CMD_RST);
920 /* Disable interrupts which might cause a timeout here */
921 flag = disable_interrupts ();
922 /* Clear the status register */
923 flash_cmd (info->portwidth, addr, 0,
924 CHIP_CMD_CLR_STAT);
925 flash_cmd (info->portwidth, addr, 0,
926 CHIP_CMD_RST);
927 /* 1st cycle of word/byte program */
928 /* write 0x40 to the location to program */
Wolfgang Denk7fb52662005-10-13 16:45:02 +0200929 flash_cmd (info->portwidth, (uchar *) dest, 0,
wdenk5da7f2f2004-01-03 00:43:19 +0000930 CHIP_CMD_PROG);
931 /* 2nd cycle of word/byte program */
932 /* write the data to the destination address */
933 *(ulong *) dest = data;
934 /* re-enable interrupts if necessary */
935 if (flag)
936 enable_interrupts ();
937 /* setup the status register mask */
938 mask = CHIP_STAT_RDY | (CHIP_STAT_RDY << 16);
939 /* put flash into read status mode by writing 0x70 to it */
940 flash_cmd (info->portwidth, addr, 0,
941 CHIP_CMD_RD_STAT);
942 /* init. the timeout counter */
943 start = get_timer (0);
944 /* keep looping while the flash is not ready */
945 /* exit the loop by timing out or the flash */
946 /* becomes ready again */
947/* 11-13-2002 Paul Marchese */
948/* modified while loop conditional statement */
949/* because we were always timing out. */
950/* there is a type mismatch, "addr[0]" */
951/* returns a byte but "mask" is a 32-bit value */
952 while ((*(volatile unsigned long *) info->
953 start[0] & mask) != mask)
954/* original code */
955/* while (addr[0] & mask) != mask) */
956 {
957 /* has the timeout limit been reached? */
958 if (get_timer (start) >
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200959 CONFIG_SYS_FLASH_WRITE_TOUT) {
wdenk5da7f2f2004-01-03 00:43:19 +0000960 /* timeout limit reached */
961 printf ("Time out limit reached programming address %08lx with data %08lx\n", dest, data);
962 /* reset the flash */
963 flash_cmd (info->portwidth,
964 addr, 0,
965 CHIP_CMD_RST);
966 return (1);
967 }
968 /* put flash into read status mode by writing 0x70 to it */
969 flash_cmd (info->portwidth, addr, 0,
970 CHIP_CMD_RD_STAT);
971 }
972 /* flash is ready, so check the status */
973 /* create the status mask to check for errors */
974 mask = CHIP_STAT_DPS | CHIP_STAT_VPPS |
975 CHIP_STAT_PSLBS;
976 mask = mask | (mask << 16);
977 /* put flash into read status mode by writing 0x70 to it */
978 flash_cmd (info->portwidth, addr, 0,
979 CHIP_CMD_RD_STAT);
980 /* are there any errors? */
981 if ((addr[0] & mask) != 0) {
982 /* We got a one of the following errors: */
983 /* Voltage range, Device protect, or programming */
984 /* return the error as a device timeout */
985 /* put flash into read status mode by writing 0x70 to it */
986 flash_cmd (info->portwidth, addr, 0,
987 CHIP_CMD_RD_STAT);
988 printf ("Flash programming error at address 0x%08lx\n", dest);
989 printf ("Flash status register contains 0x%08lx\n", (unsigned long) addr[0]);
990 /* reset the flash */
991 flash_cmd (info->portwidth, addr, 0,
992 CHIP_CMD_RST);
993 return 1;
994 }
995 /* write completed without errors */
996 /* reset the flash */
997 flash_cmd (info->portwidth, addr, 0,
998 CHIP_CMD_RST);
999 return 0;
1000 } else {
1001 /* it's not 16-bits wide, so return an error as a write timeout */
1002 /* NOTE: you can add routines here to handle other size flash */
1003 printf ("Error: Intel flash device is only %d-bits wide\n", info->chipwidth * 8);
1004 printf ("The write code only handles Intel 16-bit wide flash memory\n");
1005 return 1;
1006 }
1007 } else {
1008 /* not Intel flash so return an error as a write timeout */
1009 /* NOTE: if it's another type flash, stick its routine here */
1010 printf ("Error: The flash device is not Intel type\n");
1011 printf ("The code only supports Intel flash in a 32-bit port width\n");
1012 return 1;
1013 }
1014 }
1015
1016 /* end of 32-bit flash code */
1017 if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)
1018 return 1;
1019 if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
1020 *(unsigned long *) dest = data;
1021 return 0;
1022 }
1023 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
1024 unsigned short low = data & 0xffff;
1025 unsigned short hi = (data >> 16) & 0xffff;
1026 int ret = write_word_intel ((bank_addr_t) dest, hi);
1027
1028 if (!ret)
1029 ret = write_word_intel ((bank_addr_t) (dest + 2),
1030 low);
1031
1032 return ret;
1033 }
1034
1035 /* Check if Flash is (sufficiently) erased */
1036 if ((*((vu_long *) dest) & data) != data) {
1037 return (2);
1038 }
1039 /* Disable interrupts which might cause a timeout here */
1040 flag = disable_interrupts ();
1041
1042 /* first, perform an unlock bypass command to speed up flash writes */
1043 addr[0x555] = 0xAA;
1044 addr[0x2AA] = 0x55;
1045 addr[0x555] = 0x20;
1046
1047 /* write each byte out */
1048 for (i = 0; i < 4; i++) {
1049 char *data_ch = (char *) &data;
1050
1051 addr[0] = 0xA0;
1052 *(((char *) dest) + i) = data_ch[i];
1053 udelay (10); /* XXX */
1054 }
1055
1056 /* we're done, now do an unlock bypass reset */
1057 addr[0] = 0x90;
1058 addr[0] = 0x00;
1059
1060 /* re-enable interrupts if necessary */
1061 if (flag)
1062 enable_interrupts ();
1063
1064 /* data polling for D7 */
1065 start = get_timer (0);
1066 while ((*((vu_long *) dest) & 0x00800080) != (data & 0x00800080)) {
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +02001067 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
wdenk5da7f2f2004-01-03 00:43:19 +00001068 return (1);
1069 }
1070 }
1071 return (0);
1072}