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