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,
25 #include <asm/inca-ip.h>
27 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
29 typedef unsigned long FLASH_PORT_WIDTH
;
30 typedef volatile unsigned long FLASH_PORT_WIDTHV
;
32 #define FLASH_ID_MASK 0xFFFFFFFF
34 #define FPW FLASH_PORT_WIDTH
35 #define FPWV FLASH_PORT_WIDTHV
37 #define ORMASK(size) ((-size) & OR_AM_MSK)
39 #define FLASH29_REG_ADRS(reg) ((FPWV *)PHYS_FLASH_1 + (reg))
41 /* FLASH29 command register addresses */
43 #define FLASH29_REG_FIRST_CYCLE FLASH29_REG_ADRS (0x1555)
44 #define FLASH29_REG_SECOND_CYCLE FLASH29_REG_ADRS (0x2aaa)
45 #define FLASH29_REG_THIRD_CYCLE FLASH29_REG_ADRS (0x3555)
46 #define FLASH29_REG_FOURTH_CYCLE FLASH29_REG_ADRS (0x4555)
47 #define FLASH29_REG_FIFTH_CYCLE FLASH29_REG_ADRS (0x5aaa)
48 #define FLASH29_REG_SIXTH_CYCLE FLASH29_REG_ADRS (0x6555)
50 /* FLASH29 command definitions */
52 #define FLASH29_CMD_FIRST 0xaaaaaaaa
53 #define FLASH29_CMD_SECOND 0x55555555
54 #define FLASH29_CMD_FOURTH 0xaaaaaaaa
55 #define FLASH29_CMD_FIFTH 0x55555555
56 #define FLASH29_CMD_SIXTH 0x10101010
58 #define FLASH29_CMD_SECTOR 0x30303030
59 #define FLASH29_CMD_PROGRAM 0xa0a0a0a0
60 #define FLASH29_CMD_CHIP_ERASE 0x80808080
61 #define FLASH29_CMD_READ_RESET 0xf0f0f0f0
62 #define FLASH29_CMD_AUTOSELECT 0x90909090
63 #define FLASH29_CMD_READ 0x70707070
65 #define IN_RAM_CMD_READ 0x1
66 #define IN_RAM_CMD_WRITE 0x2
68 #define FLASH_WRITE_CMD ((ulong)(flash_write_cmd) & 0x7)+0xbf008000
69 #define FLASH_READ_CMD ((ulong)(flash_read_cmd) & 0x7)+0xbf008000
71 typedef void (*FUNCPTR_CP
)(ulong
*source
, ulong
*destination
, ulong nlongs
);
72 typedef void (*FUNCPTR_RD
)(int cmd
, FPWV
* pFA
, char * string
, int strLen
);
73 typedef void (*FUNCPTR_WR
)(int cmd
, FPWV
* pFA
, FPW value
);
75 static ulong
flash_get_size(FPWV
*addr
, flash_info_t
*info
);
76 static int write_word(flash_info_t
*info
, FPWV
*dest
, FPW data
);
77 static void flash_get_offsets(ulong base
, flash_info_t
*info
);
78 static flash_info_t
*flash_get_info(ulong base
);
80 static void load_cmd(ulong cmd
);
81 static ulong in_ram_cmd
= 0;
84 /******************************************************************************
86 * Don't change the program architecture
87 * This architecture assure the program
88 * can be relocated to scratch ram
90 static void flash_read_cmd(int cmd
, FPWV
* pFA
, char * string
, int strLen
)
100 if(cmd
== FLASH29_CMD_AUTOSELECT
)
102 *(FLASH29_REG_FIRST_CYCLE
) = FLASH29_CMD_FIRST
;
103 *(FLASH29_REG_SECOND_CYCLE
) = FLASH29_CMD_SECOND
;
104 *(FLASH29_REG_THIRD_CYCLE
) = FLASH29_CMD_AUTOSELECT
;
107 if(cmd
== FLASH29_CMD_READ
)
113 temp1
= *(int *)0xa0000000;
114 *(int *)0xbf0081f8 = temp1
+ temp
;
120 if(cmd
== FLASH29_CMD_READ_RESET
)
122 *(FLASH29_REG_FIRST_CYCLE
) = FLASH29_CMD_FIRST
;
123 *(FLASH29_REG_SECOND_CYCLE
) = FLASH29_CMD_SECOND
;
124 *(FLASH29_REG_THIRD_CYCLE
) = FLASH29_CMD_READ_RESET
;
127 *(int *)0xbf0081f8 = *(int *)0xa0000000; /* dummy read switch back to sdram interface */
130 /******************************************************************************
132 * Don't change the program architecture
133 * This architecture assure the program
134 * can be relocated to scratch ram
136 static void flash_write_cmd(int cmd
, FPWV
* pFA
, FPW value
)
138 *(FLASH29_REG_FIRST_CYCLE
) = FLASH29_CMD_FIRST
;
139 *(FLASH29_REG_SECOND_CYCLE
) = FLASH29_CMD_SECOND
;
141 if (cmd
== FLASH29_CMD_SECTOR
)
143 *(FLASH29_REG_THIRD_CYCLE
) = FLASH29_CMD_CHIP_ERASE
;
144 *(FLASH29_REG_FOURTH_CYCLE
) = FLASH29_CMD_FOURTH
;
145 *(FLASH29_REG_FIFTH_CYCLE
) = FLASH29_CMD_FIFTH
;
146 *pFA
= FLASH29_CMD_SECTOR
;
149 if (cmd
== FLASH29_CMD_SIXTH
)
151 *(FLASH29_REG_THIRD_CYCLE
) = FLASH29_CMD_CHIP_ERASE
;
152 *(FLASH29_REG_FOURTH_CYCLE
) = FLASH29_CMD_FOURTH
;
153 *(FLASH29_REG_FIFTH_CYCLE
) = FLASH29_CMD_FIFTH
;
154 *(FLASH29_REG_SIXTH_CYCLE
) = FLASH29_CMD_SIXTH
;
157 if (cmd
== FLASH29_CMD_PROGRAM
)
159 *(FLASH29_REG_THIRD_CYCLE
) = FLASH29_CMD_PROGRAM
;
163 if (cmd
== FLASH29_CMD_READ_RESET
)
165 *(FLASH29_REG_THIRD_CYCLE
) = FLASH29_CMD_READ_RESET
;
168 *(int *)0xbf0081f8 = *(int *)0xa0000000; /* dummy read switch back to sdram interface */
171 static void load_cmd(ulong cmd
)
178 if (in_ram_cmd
& cmd
) return;
180 if (cmd
== IN_RAM_CMD_READ
)
182 func
= (ulong
)flash_read_cmd
;
186 func
= (ulong
)flash_write_cmd
;
189 src
= (ulong
*)(func
& 0xfffffff8);
190 dst
= (ulong
*)0xbf008000;
191 absEntry
= (FUNCPTR_CP
)(0xbf0081d0);
192 absEntry(src
,dst
,0x38);
197 /*-----------------------------------------------------------------------
200 * sets up flash_info and returns size of FLASH (bytes)
202 unsigned long flash_init (void)
204 unsigned long size
= 0;
207 load_cmd(IN_RAM_CMD_READ
);
209 /* Init: no FLASHes known */
210 for (i
=0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; ++i
) {
211 ulong flashbase
= PHYS_FLASH_1
;
212 ulong
* buscon
= (ulong
*) INCA_IP_EBU_EBU_BUSCON0
;
214 /* Disable write protection */
215 *buscon
&= ~INCA_IP_EBU_EBU_BUSCON1_WRDIS
;
218 memset(&flash_info
[i
], 0, sizeof(flash_info_t
));
222 flash_get_size((FPW
*)flashbase
, &flash_info
[i
]);
224 if (flash_info
[i
].flash_id
== FLASH_UNKNOWN
) {
225 printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
226 i
, flash_info
[i
].size
);
229 size
+= flash_info
[i
].size
;
232 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
233 /* monitor protection ON by default */
234 flash_protect(FLAG_PROTECT_SET
,
235 CONFIG_SYS_MONITOR_BASE
,
236 CONFIG_SYS_MONITOR_BASE
+monitor_flash_len
-1,
237 flash_get_info(CONFIG_SYS_MONITOR_BASE
));
240 #ifdef CONFIG_ENV_IS_IN_FLASH
241 /* ENV protection ON by default */
242 flash_protect(FLAG_PROTECT_SET
,
244 CONFIG_ENV_ADDR
+CONFIG_ENV_SIZE
-1,
245 flash_get_info(CONFIG_ENV_ADDR
));
251 /*-----------------------------------------------------------------------
253 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
257 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
258 && (info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM160B
) {
260 int bootsect_size
[4]; /* number of bytes/boot sector */
261 int sect_size
; /* number of bytes/regular sector */
263 bootsect_size
[0] = 0x00008000;
264 bootsect_size
[1] = 0x00004000;
265 bootsect_size
[2] = 0x00004000;
266 bootsect_size
[3] = 0x00010000;
267 sect_size
= 0x00020000;
269 /* set sector offsets for bottom boot block type */
270 for (i
= 0; i
< info
->sector_count
; i
++) {
271 info
->start
[i
] = base
;
272 base
+= i
< 4 ? bootsect_size
[i
] : sect_size
;
277 /*-----------------------------------------------------------------------
280 static flash_info_t
*flash_get_info(ulong base
)
285 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; i
++) {
286 info
= & flash_info
[i
];
287 if (info
->start
[0] <= base
&& base
< info
->start
[0] + info
->size
)
291 return i
== CONFIG_SYS_MAX_FLASH_BANKS
? 0 : info
;
294 /*-----------------------------------------------------------------------
297 void flash_print_info (flash_info_t
*info
)
303 uchar botbootletter
[] = "B";
304 uchar topbootletter
[] = "T";
305 uchar botboottype
[] = "bottom boot sector";
306 uchar topboottype
[] = "top boot sector";
308 if (info
->flash_id
== FLASH_UNKNOWN
) {
309 printf ("missing or unknown FLASH type\n");
313 switch (info
->flash_id
& FLASH_VENDMASK
) {
314 case FLASH_MAN_AMD
: printf ("AMD "); break;
315 case FLASH_MAN_BM
: printf ("BRIGHT MICRO "); break;
316 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
317 case FLASH_MAN_SST
: printf ("SST "); break;
318 case FLASH_MAN_STM
: printf ("STM "); break;
319 case FLASH_MAN_INTEL
: printf ("INTEL "); break;
320 default: printf ("Unknown Vendor "); break;
323 /* check for top or bottom boot, if it applies */
324 if (info
->flash_id
& FLASH_BTYPE
) {
325 boottype
= botboottype
;
326 bootletter
= botbootletter
;
329 boottype
= topboottype
;
330 bootletter
= topbootletter
;
333 switch (info
->flash_id
& FLASH_TYPEMASK
) {
335 fmt
= "29LV160B%s (16 Mbit, %s)\n";
337 case FLASH_28F800C3B
:
338 case FLASH_28F800C3T
:
339 fmt
= "28F800C3%s (8 Mbit, %s)\n";
341 case FLASH_INTEL800B
:
342 case FLASH_INTEL800T
:
343 fmt
= "28F800B3%s (8 Mbit, %s)\n";
345 case FLASH_28F160C3B
:
346 case FLASH_28F160C3T
:
347 fmt
= "28F160C3%s (16 Mbit, %s)\n";
349 case FLASH_INTEL160B
:
350 case FLASH_INTEL160T
:
351 fmt
= "28F160B3%s (16 Mbit, %s)\n";
353 case FLASH_28F320C3B
:
354 case FLASH_28F320C3T
:
355 fmt
= "28F320C3%s (32 Mbit, %s)\n";
357 case FLASH_INTEL320B
:
358 case FLASH_INTEL320T
:
359 fmt
= "28F320B3%s (32 Mbit, %s)\n";
361 case FLASH_28F640C3B
:
362 case FLASH_28F640C3T
:
363 fmt
= "28F640C3%s (64 Mbit, %s)\n";
365 case FLASH_INTEL640B
:
366 case FLASH_INTEL640T
:
367 fmt
= "28F640B3%s (64 Mbit, %s)\n";
370 fmt
= "Unknown Chip Type\n";
374 printf (fmt
, bootletter
, boottype
);
376 printf (" Size: %ld MB in %d Sectors\n",
380 printf (" Sector Start Addresses:");
382 for (i
=0; i
<info
->sector_count
; ++i
) {
387 printf (" %08lX%s", info
->start
[i
],
388 info
->protect
[i
] ? " (RO)" : " ");
394 /*-----------------------------------------------------------------------
398 * The following code cannot be run from FLASH!
401 ulong
flash_get_size (FPWV
*addr
, flash_info_t
*info
)
407 load_cmd(IN_RAM_CMD_READ
);
408 absEntry
= (FUNCPTR_RD
)FLASH_READ_CMD
;
410 flag
= disable_interrupts();
411 absEntry(FLASH29_CMD_AUTOSELECT
,0,0,0);
412 if (flag
) enable_interrupts();
416 flag
= disable_interrupts();
417 absEntry(FLASH29_CMD_READ
, addr
+ 1, (char *)&retValue
, sizeof(retValue
));
418 absEntry(FLASH29_CMD_READ_RESET
,0,0,0);
419 if (flag
) enable_interrupts();
425 case (FPW
)AMD_ID_LV160B
:
426 info
->flash_id
+= FLASH_AM160B
;
427 info
->sector_count
= 35;
428 info
->size
= 0x00400000;
429 break; /* => 8 or 16 MB */
432 info
->flash_id
= FLASH_UNKNOWN
;
433 info
->sector_count
= 0;
435 return (0); /* => no or unknown flash */
438 flash_get_offsets((ulong
)addr
, info
);
443 /*-----------------------------------------------------------------------
446 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
449 int flag
, prot
, sect
;
450 ulong start
, now
, last
;
454 load_cmd(IN_RAM_CMD_WRITE
);
455 absEntry
= (FUNCPTR_WR
)FLASH_WRITE_CMD
;
457 if ((s_first
< 0) || (s_first
> s_last
)) {
458 if (info
->flash_id
== FLASH_UNKNOWN
) {
459 printf ("- missing\n");
461 printf ("- no sectors to erase\n");
466 switch (info
->flash_id
& FLASH_TYPEMASK
) {
471 printf ("Can't erase unknown flash type %08lx - aborted\n",
477 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
478 if (info
->protect
[sect
]) {
484 printf ("- Warning: %d protected sectors will not be erased!\n",
492 /* Start erase on unprotected sectors */
493 for (sect
= s_first
; sect
<=s_last
&& rcode
== 0; sect
++) {
495 if (info
->protect
[sect
] != 0) /* protected, skip it */
498 /* Disable interrupts which might cause a timeout here */
499 flag
= disable_interrupts();
501 addr
= (FPWV
*)(info
->start
[sect
]);
502 absEntry(FLASH29_CMD_SECTOR
, addr
, 0);
504 /* re-enable interrupts if necessary */
508 start
= get_timer(0);
510 while ((now
= get_timer(start
)) <= CONFIG_SYS_FLASH_ERASE_TOUT
) {
512 /* show that we're waiting */
513 if ((get_timer(last
)) > CONFIG_SYS_HZ
) {/* every second */
519 flag
= disable_interrupts();
520 absEntry(FLASH29_CMD_READ_RESET
,0,0);
529 /*-----------------------------------------------------------------------
530 * Copy memory to flash, returns:
533 * 2 - Flash not erased
535 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
537 FPW data
= 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
538 int bytes
; /* number of bytes to program in current word */
539 int left
; /* number of bytes left to program */
542 for (left
= cnt
, res
= 0;
543 left
> 0 && res
== 0;
544 addr
+= sizeof(data
), left
-= sizeof(data
) - bytes
) {
546 bytes
= addr
& (sizeof(data
) - 1);
547 addr
&= ~(sizeof(data
) - 1);
549 /* combine source and destination data so can program
550 * an entire word of 16 or 32 bits
552 for (i
= 0; i
< sizeof(data
); i
++) {
554 if (i
< bytes
|| i
- bytes
>= left
)
555 data
+= *((uchar
*)addr
+ i
);
560 res
= write_word(info
, (FPWV
*)addr
, data
);
566 static int write_word (flash_info_t
*info
, FPWV
*dest
, FPW data
)
568 int res
= 0; /* result, assume success */
572 /* Check if Flash is (sufficiently) erased */
573 if ((*dest
& data
) != data
) {
577 if (info
->start
[0] != PHYS_FLASH_1
)
582 load_cmd(IN_RAM_CMD_WRITE
);
583 absEntry
= (FUNCPTR_WR
)FLASH_WRITE_CMD
;
585 flag
= disable_interrupts();
586 absEntry(FLASH29_CMD_PROGRAM
,dest
,data
);
587 if (flag
) enable_interrupts();
591 flag
= disable_interrupts();
592 absEntry(FLASH29_CMD_READ_RESET
,0,0);
593 if (flag
) enable_interrupts();