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