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