Root/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
38flash_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
44typedef unsigned short FLASH_PORT_WIDTH;
45typedef volatile unsigned short FLASH_PORT_WIDTHV;
46#define FLASH_ID_MASK 0xFFFF
47#else
48typedef unsigned long FLASH_PORT_WIDTH;
49typedef 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 */
69static ulong flash_get_size(FPWV *addr, flash_info_t *info);
70static void flash_reset(flash_info_t *info);
71static int write_word_intel(flash_info_t *info, FPWV *dest, FPW data);
72static int write_word_amd(flash_info_t *info, FPWV *dest, FPW data);
73static void flash_get_offsets(ulong base, flash_info_t *info);
74static 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 */
81unsigned 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 */
147static 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 */
175static 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
298static 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
315void 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
436ulong 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
602int 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 */
759int 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 */
814static 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 */
871static 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}
918

Archive Download this file



interactive