3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
23 //joelin 10/07/2004 for MXIC MX29LV320ABTC-90
25 #include <asm/danube.h>
29 #define FLASH_DELAY {int i; \
31 *((volatile u32 *)CFG_SDRAM_BASE_UNCACHE); \
38 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
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.
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
48 typedef unsigned long FLASH_PORT_WIDTH
;
49 typedef volatile unsigned long FLASH_PORT_WIDTHV
;
50 #define FLASH_ID_MASK 0xFFFFFFFF
53 #define FPW FLASH_PORT_WIDTH
54 #define FPWV FLASH_PORT_WIDTHV
56 #define ORMASK(size) ((-size) & OR_AM_MSK) // 0xffff8000
59 #define FLASH_CYCLE1 0x0555
60 #define FLASH_CYCLE2 0x02aa
62 #define FLASH_CYCLE1 0x0554 //joelin for MX29LV320AT/B 0x0555
63 #define FLASH_CYCLE2 0x02ab //joelin for MX29LV320AT/B 0x02aa
66 /*-----------------------------------------------------------------------
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
);
76 /*-----------------------------------------------------------------------
79 * sets up flash_info and returns size of FLASH (bytes)
81 unsigned long flash_init (void)
83 unsigned long size
= 0;
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
90 volatile ulong
* buscon
= (ulong
*)
91 ((i
== 0) ? DANUBE_EBU_BUSCON0
: DANUBE_EBU_BUSCON1
);
93 /* Disable write protection */
94 // *buscon &= ~AMAZON_EBU_BUSCON0_WRDIS;
95 /* Enable write protection */
96 *buscon
|= DANUBE_EBU_BUSCON0_WRDIS
;
99 memset(&flash_info
[i
], 0, sizeof(flash_info_t
));
103 flash_get_size((FPW
*)flashbase
, &flash_info
[i
]);
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
);
110 size
+= flash_info
[i
].size
;
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,
117 CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
118 flash_get_info(CFG_MONITOR_BASE));
120 flash_protect(FLAG_PROTECT_CLEAR
, // clear protect
122 CFG_MONITOR_BASE
+CFG_MONITOR_LEN
-1,
123 flash_get_info(CFG_MONITOR_BASE
));
127 #ifdef CFG_ENV_IS_IN_FLASH /* 1 */
128 /* ENV protection ON by default */
129 /* flash_protect(FLAG_PROTECT_SET,
131 CFG_ENV_ADDR+CFG_ENV_SIZE-1,
132 flash_get_info(CFG_ENV_ADDR));
134 flash_protect(FLAG_PROTECT_CLEAR
,
136 CFG_ENV_ADDR
+CFG_ENV_SIZE
-1,
137 flash_get_info(CFG_ENV_ADDR
));
145 /*-----------------------------------------------------------------------
147 static void flash_reset(flash_info_t
*info
)
149 FPWV
*base
= (FPWV
*)(info
->start
[0]);
151 (*DANUBE_EBU_BUSCON0
)&=(~0x80000000); // enable writing
152 (*DANUBE_EBU_BUSCON1
)&=(~0x80000000); // enable writing
154 /* Put FLASH back in read mode */
155 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
){
156 *base
= (FPW
)0x00FF00FF; /* Intel Read Mode */
159 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
){
160 *base
= (FPW
)0x00F000F0; /* AMD Read Mode */
161 asm("SYNC"); //joelin
163 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_MX
){
164 *base
= (FPW
)0x00F000F0; /* MXIC Read Mode */
165 asm("SYNC"); //joelin
168 (*DANUBE_EBU_BUSCON0
)|=0x80000000; // disable writing
169 (*DANUBE_EBU_BUSCON1
)|=0x80000000; // disable writing
173 /*-----------------------------------------------------------------------
175 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
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 */
185 bootsect_size
= 0x00002000 * (sizeof(FPW
)/2);
186 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
188 /* set sector offsets for bottom boot block type */
189 for (i
= 0; i
< 8; ++i
) {
190 info
->start
[i
] = base
+ (i
* bootsect_size
);
192 for (i
= 8; i
< info
->sector_count
; i
++) {
193 info
->start
[i
] = base
+ ((i
- 7) * sect_size
);
196 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
197 && (info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM640U
) {
199 int sect_size
; /* number of bytes/sector */
201 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
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
);
207 else if(((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
208 && ((info
->flash_id
& FLASH_TYPEMASK
)==FLASH_28F128J3A
)){
211 for(i
=0;i
< info
->sector_count
; i
++)
212 info
->start
[i
]= base
+ (i
*sect_size
);
214 else if(((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
215 && ((info
->flash_id
& FLASH_TYPEMASK
)==FLASH_28F320J3A
)){
218 for(i
=0;i
< info
->sector_count
; i
++)
219 info
->start
[i
]= base
+ (i
*sect_size
);
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 */
227 bootsect_size
= 0x00002000 * (sizeof(FPW
)/2);
228 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
230 /* set sector offsets for bottom boot block type */
231 for (i
= 0; i
< 8; ++i
) {
232 info
->start
[i
] = base
+ (i
* bootsect_size
);
234 for (i
= 8; i
< info
->sector_count
; i
++) {
235 info
->start
[i
] = base
+ ((i
- 7) * sect_size
);
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 */
243 bootsect_size
= 0x00002000 * (sizeof(FPW
)/2);
244 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
246 /* set sector offsets for bottom boot block type */
247 for (i
= 0; i
< 8; ++i
) {
248 info
->start
[i
] = base
+ (i
* bootsect_size
);
250 for (i
= 8; i
< info
->sector_count
; i
++) {
251 info
->start
[i
] = base
+ ((i
- 7) * sect_size
);
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 */
260 bootsect_size
= 0x00002000 * (sizeof(FPW
)/2);
261 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
262 /* set sector offsets for bottom boot block type */
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
269 for (i
= 4; i
< info
->sector_count
; i
++) {
270 info
->start
[i
] = base
+ ((i
- 3) * sect_size
);
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 */
279 bootsect_size
= 0x00002000 * (sizeof(FPW
)/2);
280 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
282 /* set sector offsets for bottom boot block type */
283 for (i
= 0; i
< 8; ++i
) {
284 info
->start
[i
] = base
+ (i
* bootsect_size
);
286 for (i
= 8; i
< info
->sector_count
; i
++) {
287 info
->start
[i
] = base
+ ((i
- 7) * sect_size
);
291 printf("flash get offsets fail\n");
295 /*-----------------------------------------------------------------------
298 static flash_info_t
*flash_get_info(ulong base
)
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
)
309 return i
== CFG_MAX_FLASH_BANKS
? 0 : info
;
312 /*-----------------------------------------------------------------------
315 void flash_print_info (flash_info_t
*info
)
321 uchar botbootletter
[] = "B";
322 uchar topbootletter
[] = "T";
323 uchar botboottype
[] = "bottom boot sector";
324 uchar topboottype
[] = "top boot sector";
326 if (info
->flash_id
== FLASH_UNKNOWN
) {
327 printf ("missing or unknown FLASH type\n");
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;
342 /* check for top or bottom boot, if it applies */
343 if (info
->flash_id
& FLASH_BTYPE
) {
344 boottype
= botboottype
;
345 bootletter
= botbootletter
;
348 boottype
= topboottype
;
349 bootletter
= topbootletter
;
352 switch (info
->flash_id
& FLASH_TYPEMASK
) {
354 fmt
= "29LV641D (64 Mbit, uniform sectors)\n";
356 case FLASH_28F800C3B
:
357 case FLASH_28F800C3T
:
358 fmt
= "28F800C3%s (8 Mbit, %s)\n";
360 case FLASH_INTEL800B
:
361 case FLASH_INTEL800T
:
362 fmt
= "28F800B3%s (8 Mbit, %s)\n";
364 case FLASH_28F160C3B
:
365 case FLASH_28F160C3T
:
366 fmt
= "28F160C3%s (16 Mbit, %s)\n";
368 case FLASH_INTEL160B
:
369 case FLASH_INTEL160T
:
370 fmt
= "28F160B3%s (16 Mbit, %s)\n";
372 case FLASH_28F320C3B
:
373 case FLASH_28F320C3T
:
374 fmt
= "28F320C3%s (32 Mbit, %s)\n";
376 case FLASH_INTEL320B
:
377 case FLASH_INTEL320T
:
378 fmt
= "28F320B3%s (32 Mbit, %s)\n";
380 case FLASH_28F640C3B
:
381 case FLASH_28F640C3T
:
382 fmt
= "28F640C3%s (64 Mbit, %s)\n";
384 case FLASH_INTEL640B
:
385 case FLASH_INTEL640T
:
386 fmt
= "28F640B3%s (64 Mbit, %s)\n";
388 case FLASH_28F128J3A
:
389 fmt
= "28F128J3A (128 Mbit, 128 uniform sectors)\n";
391 case FLASH_28F320J3A
:
392 fmt
= "28F320J3A (32 Mbit, 32 uniform sectors)\n";
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";
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";
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";
405 fmt
= "Unknown Chip Type\n";
409 printf (fmt
, bootletter
, boottype
);
411 printf (" Size: %ld MB in %d Sectors\n",
415 printf (" Sector Start Addresses:");
417 for (i
=0; i
<info
->sector_count
; ++i
) {
422 printf (" %08lX%s", info
->start
[i
],
423 info
->protect
[i
] ? " (RO)" : " ");
429 /*-----------------------------------------------------------------------
433 * The following code cannot be run from FLASH!
436 ulong
flash_get_size (FPWV
*addr
, flash_info_t
*info
)
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
441 (*DANUBE_EBU_BUSCON0
)&=(~0x80000000); // enable writing
442 (*DANUBE_EBU_BUSCON1
)&=(~0x80000000); // enable writing
443 /* Write auto select command: read Manufacturer ID */
445 /* Write auto select command sequence and test FLASH answer */
446 addr
[FLASH_CYCLE1
] = (FPW
)0x00AA00AA; /* for AMD, Intel ignores this */
448 addr
[FLASH_CYCLE2
] = (FPW
)0x00550055; /* for AMD, Intel ignores this */
450 addr
[FLASH_CYCLE1
] = (FPW
)0x00900090; /* selects Intel or AMD */
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.
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
460 switch (addr
[1] & 0xff) {
461 case (uchar
)AMD_MANUFACT
:
462 info
->flash_id
= FLASH_MAN_AMD
;
465 case (uchar
)INTEL_MANUFACT
: // 0x0089
466 info
->flash_id
= FLASH_MAN_INTEL
; //0x00300000
470 case (uchar
)MX_MANUFACT
: // 0x00c2
471 info
->flash_id
= FLASH_MAN_MX
;//0x00030000
475 info
->flash_id
= FLASH_UNKNOWN
;
476 info
->sector_count
= 0;
480 info->flash_id = FLASH_MAN_INTEL; //0x00300000
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);
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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);
556 case (FPW
)MX_ID_29LV320AB
:
557 info
->flash_id
+= FLASH_29LV320AB
;
558 info
->sector_count
= 71;
559 info
->size
= 0x00400000 * (sizeof(FPW
)/2);
563 case (FPW
)MX_ID_29LV160BB
:
564 info
->flash_id
+= FLASH_29LV160BB
;
565 info
->sector_count
= 35;
566 info
->size
= 0x00200000 * (sizeof(FPW
)/2);
570 case (FPW
)MX_ID_29LV640BB
:
571 info
->flash_id
+= FLASH_29LV640BB
;
572 info
->sector_count
= 135;
573 info
->size
= 0x00800000 * (sizeof(FPW
)/2);
576 info
->flash_id
= FLASH_UNKNOWN
;
577 info
->sector_count
= 0;
579 return (0); /* => no or unknown flash */
581 info->flash_id += FLASH_28F320J3A;
582 info->sector_count = 32;
583 info->size = 0x00400000 * (sizeof(FPW)/2);
588 (*DANUBE_EBU_BUSCON0
)|=0x80000000; // disable writing
589 (*DANUBE_EBU_BUSCON1
)|=0x80000000; // disable writing
591 flash_get_offsets((ulong
)addr
, info
);
593 /* Put FLASH back in read mode */
599 /*-----------------------------------------------------------------------
602 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
605 int flag
, prot
, sect
;
606 int intel
= (info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
;
607 ulong start
, now
, last
;
609 if ((s_first
< 0) || (s_first
> s_last
)) {
610 if (info
->flash_id
== FLASH_UNKNOWN
) {
611 printf ("- missing\n");
613 printf ("- no sectors to erase\n");
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
:
630 case FLASH_29LV640BB
: //liupeng for MXIC MX29LV640BB
632 case FLASH_29LV320AB
: //joelin for MXIC MX29LV320AB
633 case FLASH_29LV160BB
: //joelin for MXIC MX29LV160BB
637 printf ("Can't erase unknown flash type %08lx - aborted\n",
643 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
644 if (info
->protect
[sect
]) {
650 printf ("- Warning: %d protected sectors will not be erased!\n",
658 /* Start erase on unprotected sectors */
659 for (sect
= s_first
; sect
<=s_last
&& rcode
== 0; sect
++) {
661 if (info
->protect
[sect
] != 0) /* protected, skip it */
664 /* Disable interrupts which might cause a timeout here */
665 flag
= disable_interrupts();
667 (*DANUBE_EBU_BUSCON0
)&=(~0x80000000); // enable writing
668 (*DANUBE_EBU_BUSCON1
)&=(~0x80000000); // enable writing
670 addr
= (FPWV
*)(info
->start
[sect
]);
672 *addr
= (FPW
)0x00500050; /* clear status register */
673 *addr
= (FPW
)0x00200020; /* erase setup */
674 *addr
= (FPW
)0x00D000D0; /* erase confirm */
678 /* must be AMD style if not Intel */
679 FPWV
*base
; /* first address in bank */
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 */
690 /* re-enable interrupts if necessary */
694 start
= get_timer(0);
696 /* wait at least 50us for AMD, 80us for Intel.
701 while ((*addr
& (FPW
)0x00800080) != (FPW
)0x00800080) {
702 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
703 printf ("Erase Timeout\n");
707 *addr
= (FPW
)0x00B000B0;
710 flash_reset(info
); /* reset to read mode */
711 rcode
= 1; /* failed */
715 /* show that we're waiting */
716 if ((get_timer(last
)) > CFG_HZ
) {/* every second */
724 switch (info
->flash_id
& FLASH_VENDMASK
) {
725 case FLASH_MAN_MX
: //joelin for MXIC
728 if((*addr
& (FPW
)0x00200020) != (FPW
)0x0)
729 printf("Erase Error\n");
735 /* show that we're waiting */
736 if ((get_timer(last
)) > CFG_HZ
) { /* every second */
741 //flash_reset(info); /* reset to read mode */
744 (*DANUBE_EBU_BUSCON0
)|=0x80000000; // disable writing
745 (*DANUBE_EBU_BUSCON1
)|=0x80000000; // disable writing
747 flash_reset(info
); /* Homebox Black with JS28F128J3D75 had trouble reading after erase */
753 /*-----------------------------------------------------------------------
754 * Copy memory to flash, returns:
757 * 2 - Flash not erased
759 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
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 */
766 for (left
= cnt
, res
= 0;
767 left
> 0 && res
== 0;
768 addr
+= sizeof(data
), left
-= sizeof(data
) - bytes
) {
770 bytes
= addr
& (sizeof(data
) - 1);
771 addr
&= ~(sizeof(data
) - 1);
773 /* combine source and destination data so can program
774 * an entire word of 16 or 32 bits
776 for (i
= 0; i
< sizeof(data
); i
++) {
778 if (i
< bytes
|| i
- bytes
>= left
)
779 data
+= *((uchar
*)addr
+ i
);
784 /* write one word to the flash */
785 switch (info
->flash_id
& FLASH_VENDMASK
) {
787 case FLASH_MAN_MX
: //joelin for MXIC
788 res
= write_word_amd(info
, (FPWV
*)addr
, data
);
790 case FLASH_MAN_INTEL
:
791 res
= write_word_intel(info
, (FPWV
*)addr
, data
);
794 /* unknown flash type, error! */
795 printf ("missing or unknown FLASH type\n");
796 res
= 1; /* not really a timeout, but gives error */
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.
812 * 2 - Flash not erased
814 static int write_word_amd (flash_info_t
*info
, FPWV
*dest
, FPW data
)
818 int res
= 0; /* result, assume success */
819 FPWV
*base
; /* first address in flash bank */
821 /* Check if Flash is (sufficiently) erased */
822 if ((*dest
& data
) != data
) {
826 base
= (FPWV
*)(info
->start
[0]);
828 /* Disable interrupts which might cause a timeout here */
829 flag
= disable_interrupts();
831 (*DANUBE_EBU_BUSCON0
)&=(~0x80000000); // enable writing
832 (*DANUBE_EBU_BUSCON1
)&=(~0x80000000); // enable writing
835 base
[FLASH_CYCLE1
] = (FPW
)0x00AA00AA; /* unlock */
836 base
[FLASH_CYCLE2
] = (FPW
)0x00550055; /* unlock */
837 base
[FLASH_CYCLE1
] = (FPW
)0x00A000A0; /* selects program mode */
839 *dest
= data
; /* start programming the data */
841 /* re-enable interrupts if necessary */
845 start
= get_timer (0);
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 */
855 (*DANUBE_EBU_BUSCON0
)|=0x80000000; // disable writing
856 (*DANUBE_EBU_BUSCON1
)|=0x80000000; // disable writing
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.
869 * 2 - Flash not erased
871 static int write_word_intel (flash_info_t
*info
, FPWV
*dest
, FPW data
)
875 int res
= 0; /* result, assume success */
877 /* Check if Flash is (sufficiently) erased */
878 if ((*dest
& data
) != data
) {
882 /* Disable interrupts which might cause a timeout here */
883 flag
= disable_interrupts();
885 (*DANUBE_EBU_BUSCON0
)&=(~0x80000000); // enable writing
886 (*DANUBE_EBU_BUSCON1
)&=(~0x80000000); // enable writing
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 */
894 /* re-enable interrupts if necessary */
898 start
= get_timer (0);
900 while (res
== 0 && (*dest
& (FPW
)0x00800080) != (FPW
)0x00800080) {
901 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
902 *dest
= (FPW
)0x00B000B0; /* Suspend program */
907 if (res
== 0 && (*dest
& (FPW
)0x00100010))
908 res
= 1; /* write failed, time out error is close enough */
910 *dest
= (FPW
)0x00500050; /* clear status register */
913 (*DANUBE_EBU_BUSCON0
)|=0x80000000; // disable writing
914 (*DANUBE_EBU_BUSCON1
)|=0x80000000; // disable writing
This page took 0.116193 seconds and 5 git commands to generate.