[backfire] merge r27449
[10.03/openwrt.git] / package / uboot-ifxmips / files / board / ifx / 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         else if(((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
239                 && ((info->flash_id & FLASH_TYPEMASK)==FLASH_29LV320B)){
240                 int bootsect_size;      /* number of bytes/boot sector  */
241                 int sect_size;          /* number of bytes/regular sector */
242
243                 bootsect_size = 0x00002000 * (sizeof(FPW)/2);
244                 sect_size =     0x00010000 * (sizeof(FPW)/2);
245
246                 /* set sector offsets for bottom boot block type        */
247                 for (i = 0; i < 8; ++i) {
248                         info->start[i] = base + (i * bootsect_size);
249                 }
250                 for (i = 8; i < info->sector_count; i++) {
251                         info->start[i] = base + ((i - 7) * sect_size);
252                 }
253         }       
254 //joelin add for MX29LV160BB-- SA0=16K,SA1,SA2=8K,SA3=32K bytes ,SA4~SA34 :sector size=64k bytes                        
255         else if(((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_MX)
256                 && ((info->flash_id & FLASH_TYPEMASK)==FLASH_29LV160BB)){
257                 int bootsect_size;      /* number of bytes/boot sector  */
258                 int sect_size;          /* number of bytes/regular sector */
259
260                 bootsect_size = 0x00002000 * (sizeof(FPW)/2);
261                 sect_size =     0x00010000 * (sizeof(FPW)/2);
262 /* set sector offsets for bottom boot block type        */              
263 //MX29LV160BB
264                 info->start[0] = base ;                         //SA0=16K bytes
265                 info->start[1] = info->start[0]  + (1 * 0x00004000 * (sizeof(FPW)/2)); //SA1=8K bytes
266                 info->start[2] = info->start[1]  + (1 * 0x00002000 * (sizeof(FPW)/2)); //SA2=8K bytes
267                 info->start[3] = info->start[2]  + (1 * 0x00002000 * (sizeof(FPW)/2)); //SA3=32K bytes
268
269                 for (i = 4; i < info->sector_count; i++) {
270                         info->start[i] = base + ((i - 3) * sect_size);
271                 }               
272         }       
273 //liupeng add for MX29LV640BB-- SA0~SA7:sector size=8k bytes ,SA8~SA134 :sector size=64k bytes  
274         else if(((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_MX)
275                 && ((info->flash_id & FLASH_TYPEMASK)==FLASH_29LV640BB)){
276                 int bootsect_size;      /* number of bytes/boot sector  */
277                 int sect_size;          /* number of bytes/regular sector */
278
279                 bootsect_size = 0x00002000 * (sizeof(FPW)/2);
280                 sect_size =     0x00010000 * (sizeof(FPW)/2);
281
282                 /* set sector offsets for bottom boot block type        */
283                 for (i = 0; i < 8; ++i) {
284                         info->start[i] = base + (i * bootsect_size);
285                 }
286                 for (i = 8; i < info->sector_count; i++) {
287                         info->start[i] = base + ((i - 7) * sect_size);
288                 }
289         }       
290         else{
291                 printf("flash get offsets fail\n");
292         }
293 }
294
295 /*-----------------------------------------------------------------------
296  */
297
298 static flash_info_t *flash_get_info(ulong base)
299 {
300         int i;
301         flash_info_t * info;
302         
303         for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
304                 info = & flash_info[i];
305                 if (info->start[0] <= base && base < info->start[0] + info->size)
306                         break;
307         }
308         
309         return i == CFG_MAX_FLASH_BANKS ? 0 : info;
310 }
311
312 /*-----------------------------------------------------------------------
313  */
314
315 void flash_print_info (flash_info_t *info)
316 {
317         int i;
318         uchar *boottype;
319         uchar *bootletter;
320         uchar *fmt;
321         uchar botbootletter[] = "B";
322         uchar topbootletter[] = "T";
323         uchar botboottype[] = "bottom boot sector";
324         uchar topboottype[] = "top boot sector";
325
326         if (info->flash_id == FLASH_UNKNOWN) {
327                 printf ("missing or unknown FLASH type\n");
328                 return;
329         }
330
331         switch (info->flash_id & FLASH_VENDMASK) {
332         case FLASH_MAN_AMD:     printf ("AMD ");                break;
333         case FLASH_MAN_BM:      printf ("BRIGHT MICRO ");       break;
334         case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
335         case FLASH_MAN_SST:     printf ("SST ");                break;
336         case FLASH_MAN_STM:     printf ("STM ");                break;
337         case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
338         case FLASH_MAN_MX:      printf ("MXIC  ");              break;  
339         default:                printf ("Unknown Vendor ");     break;
340         }
341
342         /* check for top or bottom boot, if it applies */
343         if (info->flash_id & FLASH_BTYPE) {
344                 boottype = botboottype;
345                 bootletter = botbootletter;
346         }
347         else {
348                 boottype = topboottype;
349                 bootletter = topbootletter;
350         }
351
352         switch (info->flash_id & FLASH_TYPEMASK) {
353         case FLASH_AM640U:
354                 fmt = "29LV641D (64 Mbit, uniform sectors)\n";
355                 break;
356         case FLASH_28F800C3B:
357         case FLASH_28F800C3T:
358                 fmt = "28F800C3%s (8 Mbit, %s)\n";
359                 break;
360         case FLASH_INTEL800B:
361         case FLASH_INTEL800T:
362                 fmt = "28F800B3%s (8 Mbit, %s)\n";
363                 break;
364         case FLASH_28F160C3B:
365         case FLASH_28F160C3T:
366                 fmt = "28F160C3%s (16 Mbit, %s)\n";
367                 break;
368         case FLASH_INTEL160B:
369         case FLASH_INTEL160T:
370                 fmt = "28F160B3%s (16 Mbit, %s)\n";
371                 break;
372         case FLASH_28F320C3B:
373         case FLASH_28F320C3T:
374                 fmt = "28F320C3%s (32 Mbit, %s)\n";
375                 break;
376         case FLASH_INTEL320B:
377         case FLASH_INTEL320T:
378                 fmt = "28F320B3%s (32 Mbit, %s)\n";
379                 break;
380         case FLASH_28F640C3B:
381         case FLASH_28F640C3T:
382                 fmt = "28F640C3%s (64 Mbit, %s)\n";
383                 break;
384         case FLASH_INTEL640B:
385         case FLASH_INTEL640T:
386                 fmt = "28F640B3%s (64 Mbit, %s)\n";
387                 break;
388         case FLASH_28F128J3A:
389                 fmt = "28F128J3A (128 Mbit, 128 uniform sectors)\n";
390                 break;
391         case FLASH_28F320J3A:
392                 fmt = "28F320J3A (32 Mbit, 32 uniform sectors)\n";
393                 break;
394         case FLASH_29LV640BB:           //liupeng for MXIC FLASH_29LV640BB
395                 fmt = "29LV640BB (64 Mbit, boot sector SA0~SA126 size 64k bytes,other sectors SA127~SA135 size 8k bytes)\n";
396                 break;  
397         case FLASH_29LV320B:            //joelin for MXIC FLASH_29LV320AB
398         case FLASH_29LV320AB:           //joelin for MXIC FLASH_29LV320AB
399                 fmt = "29LV320AB (32 Mbit, boot sector SA0~SA7 size 8K bytes,other sectors SA8~SA70 size 64K bytes)\n";
400                 break;  
401         case FLASH_29LV160BB:           //joelin for MXIC FLASH_29LV160BB
402                 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";
403                 break;                                  
404         default:
405                 fmt = "Unknown Chip Type\n";
406                 break;
407         }
408
409         printf (fmt, bootletter, boottype);
410
411         printf ("  Size: %ld MB in %d Sectors\n",
412                 info->size >> 20,
413                 info->sector_count);
414
415         printf ("  Sector Start Addresses:");
416
417         for (i=0; i<info->sector_count; ++i) {
418                 if ((i % 5) == 0) {
419                         printf ("\n   ");
420                 }
421
422                 printf (" %08lX%s", info->start[i],
423                         info->protect[i] ? " (RO)" : "     ");
424         }
425
426         printf ("\n");
427 }
428
429 /*-----------------------------------------------------------------------
430  */
431
432 /*
433  * The following code cannot be run from FLASH!
434  */
435
436 ulong flash_get_size (FPWV *addr, flash_info_t *info)
437 {
438         (*DANUBE_EBU_BUSCON0)=0x1d7ff;  //value from Aikann, should be used on the real chip
439         (*EBU_ADDR_SEL_0) = 0x10000031; //starting address from 0xb0000000
440         (*EBU_NAND_CON)=0;
441         (*DANUBE_EBU_BUSCON0)&=(~0x80000000);   // enable writing
442         (*DANUBE_EBU_BUSCON1)&=(~0x80000000);   // enable writing
443         /* Write auto select command: read Manufacturer ID */
444
445         /* Write auto select command sequence and test FLASH answer */
446         addr[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* for AMD, Intel ignores this */
447         asm("SYNC");    
448         addr[FLASH_CYCLE2] = (FPW)0x00550055;   /* for AMD, Intel ignores this */
449         asm("SYNC");
450         addr[FLASH_CYCLE1] = (FPW)0x00900090;   /* selects Intel or AMD */
451         asm("SYNC");
452         
453         /* The manufacturer codes are only 1 byte, so just use 1 byte.
454          * This works for any bus width and any FLASH device width.
455          */
456  
457         printf("\n type is %08lx", addr[1] & 0xff);     //joelin 10/06/2004 flash type
458         printf("\n type is %08lx", addr[0] & 0xff);     //joelin 10/06/2004 flash type
459 //              asm("SYNC");     
460         switch (addr[1] & 0xff) {
461         case (uchar)AMD_MANUFACT:
462                 info->flash_id = FLASH_MAN_AMD;
463                 break;
464
465         case (uchar)INTEL_MANUFACT:                     // 0x0089
466                 info->flash_id = FLASH_MAN_INTEL; //0x00300000
467                 break;
468                 
469 //joelin for MXIC               
470         case (uchar)MX_MANUFACT:                // 0x00c2
471                 info->flash_id = FLASH_MAN_MX ;//0x00030000
472                 break;
473                 
474         default:
475                 info->flash_id = FLASH_UNKNOWN;
476                 info->sector_count = 0;
477                 info->size = 0;
478                 break;
479 /*      default:
480                 info->flash_id = FLASH_MAN_INTEL; //0x00300000
481                 break;*/
482         }
483
484         /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
485         if (info->flash_id != FLASH_UNKNOWN) switch (addr[0]) {
486         case (FPW)EON_ID_EN29LV320B:
487                 info->flash_id += FLASH_29LV320B;
488                 info->sector_count = 71;
489                 info->size = 0x00400000 * (sizeof(FPW)/2);
490                 break;
491         case (FPW)AMD_ID_LV640U:        /* 29LV640 and 29LV641 have same ID */
492                 info->flash_id += FLASH_AM640U;
493                 info->sector_count = 128;
494                 info->size = 0x00800000 * (sizeof(FPW)/2);
495                 break;                          /* => 8 or 16 MB        */
496
497         case (FPW)INTEL_ID_28F800C3B:
498                 info->flash_id += FLASH_28F800C3B;
499                 info->sector_count = 23;
500                 info->size = 0x00100000 * (sizeof(FPW)/2);
501                 break;                          /* => 1 or 2 MB         */
502
503         case (FPW)INTEL_ID_28F800B3B:
504                 info->flash_id += FLASH_INTEL800B;
505                 info->sector_count = 23;
506                 info->size = 0x00100000 * (sizeof(FPW)/2);
507                 break;                          /* => 1 or 2 MB         */
508
509         case (FPW)INTEL_ID_28F160C3B:
510                 info->flash_id += FLASH_28F160C3B;
511                 info->sector_count = 39;
512                 info->size = 0x00200000 * (sizeof(FPW)/2);
513                 break;                          /* => 2 or 4 MB         */
514
515         case (FPW)INTEL_ID_28F160B3B:
516                 info->flash_id += FLASH_INTEL160B;
517                 info->sector_count = 39;
518                 info->size = 0x00200000 * (sizeof(FPW)/2);
519                 break;                          /* => 2 or 4 MB         */
520
521         case (FPW)INTEL_ID_28F320C3B:
522                 info->flash_id += FLASH_28F320C3B;
523                 info->sector_count = 71;
524                 info->size = 0x00400000 * (sizeof(FPW)/2);
525                 break;                          /* => 4 or 8 MB         */
526
527         case (FPW)INTEL_ID_28F320B3B:
528                 info->flash_id += FLASH_INTEL320B;
529                 info->sector_count = 71;
530                 info->size = 0x00400000 * (sizeof(FPW)/2);
531                 break;                          /* => 4 or 8 MB         */
532
533         case (FPW)INTEL_ID_28F640C3B:
534                 info->flash_id += FLASH_28F640C3B;
535                 info->sector_count = 135;
536                 info->size = 0x00800000 * (sizeof(FPW)/2);
537                 break;                          /* => 8 or 16 MB        */
538
539         case (FPW)INTEL_ID_28F640B3B:
540                 info->flash_id += FLASH_INTEL640B;
541                 info->sector_count = 135;
542                 info->size = 0x00800000 * (sizeof(FPW)/2);
543                 break;                          /* => 8 or 16 MB        */
544         
545         case (FPW)INTEL_ID_28F128J3A:
546                 info->flash_id +=FLASH_28F128J3A;
547                 info->sector_count = 128;
548                 info->size = 0x01000000 * (sizeof(FPW)/2);
549                 break;                          /* => 16 MB */
550         case (FPW)INTEL_ID_28F320J3A:
551                 info->flash_id += FLASH_28F320J3A;
552                 info->sector_count = 32;
553                 info->size = 0x00400000 * (sizeof(FPW)/2);
554                 break;  
555 //joelin for MXIC
556         case (FPW)MX_ID_29LV320AB:
557                 info->flash_id += FLASH_29LV320AB;
558                 info->sector_count = 71;
559                 info->size = 0x00400000 * (sizeof(FPW)/2);
560                 break;                          /* => 4 MB              */              
561                                         /* => 4 MB */
562 //joelin for MXIC
563         case (FPW)MX_ID_29LV160BB:
564                 info->flash_id += FLASH_29LV160BB;
565                 info->sector_count = 35;
566                 info->size = 0x00200000 * (sizeof(FPW)/2);
567                 break;                          /* => 2 MB              */              
568                                         /* => 2 MB */                                   
569         /* liupeng*/
570         case (FPW)MX_ID_29LV640BB:
571                 info->flash_id += FLASH_29LV640BB;
572                 info->sector_count = 135;
573                 info->size = 0x00800000 * (sizeof(FPW)/2);
574                 break;                          /* => 2 MB              */              
575         default:
576                 info->flash_id = FLASH_UNKNOWN;
577                 info->sector_count = 0;
578                 info->size = 0;
579                 return (0);                     /* => no or unknown flash */
580 /*      default:
581                 info->flash_id += FLASH_28F320J3A;
582                 info->sector_count = 32;
583                 info->size = 0x00400000 * (sizeof(FPW)/2);
584                 break;*/
585         }
586
587
588         (*DANUBE_EBU_BUSCON0)|=0x80000000;      // disable writing
589         (*DANUBE_EBU_BUSCON1)|=0x80000000;      // disable writing
590         
591         flash_get_offsets((ulong)addr, info);
592
593         /* Put FLASH back in read mode */
594         flash_reset(info);
595         
596         return (info->size);
597 }
598
599 /*-----------------------------------------------------------------------
600  */
601
602 int     flash_erase (flash_info_t *info, int s_first, int s_last)
603 {
604         FPWV *addr;
605         int flag, prot, sect;
606         int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
607         ulong start, now, last;
608         int rcode = 0;
609         if ((s_first < 0) || (s_first > s_last)) {
610                 if (info->flash_id == FLASH_UNKNOWN) {
611                         printf ("- missing\n");
612                 } else {
613                         printf ("- no sectors to erase\n");
614                 }
615                 return 1;
616         }
617
618         switch (info->flash_id & FLASH_TYPEMASK) {
619         case FLASH_INTEL800B:
620         case FLASH_INTEL160B:
621         case FLASH_INTEL320B:
622         case FLASH_INTEL640B:
623         case FLASH_28F800C3B:
624         case FLASH_28F160C3B:
625         case FLASH_28F320C3B:
626         case FLASH_28F640C3B:
627         case FLASH_28F128J3A:
628         case FLASH_28F320J3A:
629         case FLASH_AM640U:
630         case FLASH_29LV640BB:   //liupeng for MXIC MX29LV640BB
631         case FLASH_29LV320B:
632         case FLASH_29LV320AB:   //joelin for MXIC MX29LV320AB
633         case FLASH_29LV160BB:   //joelin for MXIC MX29LV160BB
634                 break;
635         case FLASH_UNKNOWN:
636         default:
637                 printf ("Can't erase unknown flash type %08lx - aborted\n",
638                         info->flash_id);
639                 return 1;
640         }
641
642         prot = 0;
643         for (sect=s_first; sect<=s_last; ++sect) {
644                 if (info->protect[sect]) {
645                         prot++;
646                 }
647         }
648
649         if (prot) {
650                 printf ("- Warning: %d protected sectors will not be erased!\n",
651                         prot);
652         } else {
653                 printf ("\n");
654         }
655
656         last  = get_timer(0);
657
658         /* Start erase on unprotected sectors */
659         for (sect = s_first; sect<=s_last && rcode == 0; sect++) {
660
661                 if (info->protect[sect] != 0)   /* protected, skip it */
662                         continue;
663
664                 /* Disable interrupts which might cause a timeout here */
665                 flag = disable_interrupts();
666                 
667                 (*DANUBE_EBU_BUSCON0)&=(~0x80000000);   // enable writing
668                 (*DANUBE_EBU_BUSCON1)&=(~0x80000000);   // enable writing
669                 (*EBU_NAND_CON)=0;
670                 addr = (FPWV *)(info->start[sect]);
671                 if (intel) {
672                         *addr = (FPW)0x00500050; /* clear status register */
673                         *addr = (FPW)0x00200020; /* erase setup */
674                         *addr = (FPW)0x00D000D0; /* erase confirm */
675                         asm("SYNC");
676                 }
677                 else {
678                         /* must be AMD style if not Intel */
679                         FPWV *base;             /* first address in bank */
680
681                         base = (FPWV *)(info->start[0]);
682                         base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
683                         base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
684                         base[FLASH_CYCLE1] = (FPW)0x00800080;   /* erase mode */
685                         base[FLASH_CYCLE1] = (FPW)0x00AA00AA;   /* unlock */
686                         base[FLASH_CYCLE2] = (FPW)0x00550055;   /* unlock */
687                         *addr = (FPW)0x00300030;        /* erase sector */
688                 }
689
690                 /* re-enable interrupts if necessary */
691                 if (flag)
692                         enable_interrupts();
693
694                 start = get_timer(0);
695
696                 /* wait at least 50us for AMD, 80us for Intel.
697                  * Let's wait 1 ms.
698                  */
699                 udelay (1000);
700
701                 while ((*addr & (FPW)0x00800080) != (FPW)0x00800080) {
702                         if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
703                                 printf ("Erase Timeout\n");
704
705                                 if (intel) {
706                                         /* suspend erase        */
707                                         *addr = (FPW)0x00B000B0;
708                                 }
709
710                                 flash_reset(info);      /* reset to read mode */
711                                 rcode = 1;              /* failed */
712                                 break;
713                         }
714
715                         /* show that we're waiting */
716                         if ((get_timer(last)) > CFG_HZ) {/* every second */
717                                 putc ('.');
718                                 last = get_timer(0);
719                         }
720                 }
721                 
722                         
723 //joelin for MXIC 
724         switch (info->flash_id & FLASH_VENDMASK) {
725         case FLASH_MAN_MX:              //joelin for MXIC       
726                 break;
727         default:
728                 if((*addr & (FPW)0x00200020) != (FPW)0x0)
729                         printf("Erase Error\n");
730                 break;
731         }                       
732                         
733                         
734
735                 /* show that we're waiting */
736                 if ((get_timer(last)) > CFG_HZ) {       /* every second */
737                         putc ('.');
738                         last = get_timer(0);
739                 }
740
741                 //flash_reset(info);    /* reset to read mode   */
742         }
743
744         (*DANUBE_EBU_BUSCON0)|=0x80000000;      // disable writing
745         (*DANUBE_EBU_BUSCON1)|=0x80000000;      // disable writing
746
747         flash_reset(info);      /* Homebox Black with JS28F128J3D75 had trouble reading after erase */
748
749         printf (" done\n");
750         return rcode;
751 }
752
753 /*-----------------------------------------------------------------------
754  * Copy memory to flash, returns:
755  * 0 - OK
756  * 1 - write timeout
757  * 2 - Flash not erased
758  */
759 int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
760 {
761     FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
762     int bytes;    /* number of bytes to program in current word         */
763     int left;     /* number of bytes left to program                    */
764     int i, res;
765
766     for (left = cnt, res = 0;
767          left > 0 && res == 0;
768          addr += sizeof(data), left -= sizeof(data) - bytes) {
769
770         bytes = addr & (sizeof(data) - 1);
771         addr &= ~(sizeof(data) - 1);
772
773         /* combine source and destination data so can program
774          * an entire word of 16 or 32 bits
775          */
776         for (i = 0; i < sizeof(data); i++) {
777             data <<= 8;
778             if (i < bytes || i - bytes >= left )
779                 data += *((uchar *)addr + i);
780             else
781                 data += *src++;
782         }
783
784         /* write one word to the flash */
785         switch (info->flash_id & FLASH_VENDMASK) {
786         case FLASH_MAN_AMD:
787         case FLASH_MAN_MX:              //joelin for MXIC       
788                 res = write_word_amd(info, (FPWV *)addr, data);
789                 break;
790         case FLASH_MAN_INTEL:
791                 res = write_word_intel(info, (FPWV *)addr, data);
792                 break;
793         default:
794                 /* unknown flash type, error! */
795                 printf ("missing or unknown FLASH type\n");
796                 res = 1;        /* not really a timeout, but gives error */
797                 break;
798         }
799     }
800
801     return (res);
802 }
803
804 /*-----------------------------------------------------------------------
805  * Write a word to Flash for AMD FLASH
806  * A word is 16 or 32 bits, whichever the bus width of the flash bank
807  * (not an individual chip) is.
808  *
809  * returns:
810  * 0 - OK
811  * 1 - write timeout
812  * 2 - Flash not erased
813  */
814 static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data)
815 {
816     ulong start;
817     int flag;
818     int res = 0;        /* result, assume success       */
819     FPWV *base;         /* first address in flash bank  */
820
821     /* Check if Flash is (sufficiently) erased */
822     if ((*dest & data) != data) {
823         return (2);
824     }
825
826     base = (FPWV *)(info->start[0]);
827
828     /* Disable interrupts which might cause a timeout here */
829     flag = disable_interrupts();
830   
831     (*DANUBE_EBU_BUSCON0)&=(~0x80000000);       // enable writing
832     (*DANUBE_EBU_BUSCON1)&=(~0x80000000);       // enable writing
833     (*EBU_NAND_CON)=0;
834         
835     base[FLASH_CYCLE1] = (FPW)0x00AA00AA;       /* unlock */
836     base[FLASH_CYCLE2] = (FPW)0x00550055;       /* unlock */
837     base[FLASH_CYCLE1] = (FPW)0x00A000A0;       /* selects program mode */
838
839     *dest = data;               /* start programming the data   */
840
841     /* re-enable interrupts if necessary */
842     if (flag)
843         enable_interrupts();
844
845     start = get_timer (0);
846
847     /* data polling for D7 */
848     while (res == 0 && (*dest & (FPW)0x00800080) != (data & (FPW)0x00800080)) {
849         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
850             *dest = (FPW)0x00F000F0;    /* reset bank */
851             res = 1;
852         }
853     }
854  
855         (*DANUBE_EBU_BUSCON0)|=0x80000000;      // disable writing
856         (*DANUBE_EBU_BUSCON1)|=0x80000000;      // disable writing
857  
858         return (res);
859 }
860
861 /*-----------------------------------------------------------------------
862  * Write a word to Flash for Intel FLASH
863  * A word is 16 or 32 bits, whichever the bus width of the flash bank
864  * (not an individual chip) is.
865  *
866  * returns:
867  * 0 - OK
868  * 1 - write timeout
869  * 2 - Flash not erased
870  */
871 static int write_word_intel (flash_info_t *info, FPWV *dest, FPW data)
872 {
873     ulong start;
874     int flag;
875     int res = 0;        /* result, assume success       */
876         
877     /* Check if Flash is (sufficiently) erased */
878     if ((*dest & data) != data) {
879         return (2);
880     }
881
882     /* Disable interrupts which might cause a timeout here */
883     flag = disable_interrupts();
884
885     (*DANUBE_EBU_BUSCON0)&=(~0x80000000);       // enable writing
886     (*DANUBE_EBU_BUSCON1)&=(~0x80000000);       // enable writing
887     (*EBU_NAND_CON)=0;
888     *dest = (FPW)0x00500050;    /* clear status register        */
889     *dest = (FPW)0x00FF00FF;    /* make sure in read mode       */
890     *dest = (FPW)0x00400040;    /* program setup                */
891     *dest = data;               /* start programming the data   */
892     asm("SYNC");
893     
894     /* re-enable interrupts if necessary */
895     if (flag)
896         enable_interrupts();
897
898     start = get_timer (0);
899
900     while (res == 0 && (*dest & (FPW)0x00800080) != (FPW)0x00800080) {
901         if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
902             *dest = (FPW)0x00B000B0;    /* Suspend program      */
903             res = 1;
904         }
905     }
906
907     if (res == 0 && (*dest & (FPW)0x00100010))
908         res = 1;        /* write failed, time out error is close enough */
909
910     *dest = (FPW)0x00500050;    /* clear status register        */
911     flash_reset(info);
912
913     (*DANUBE_EBU_BUSCON0)|=0x80000000;  // disable writing
914     (*DANUBE_EBU_BUSCON1)|=0x80000000;  // disable writing
915  
916         return (res);
917 }