3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 * Keith Outwater, keith_outwater@mvsi.com
6 * See file CREDITS for list of people who contributed to this
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 #if defined(CFG_ENV_IS_IN_FLASH)
30 # define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
33 # define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
35 # ifndef CFG_ENV_SECT_SIZE
36 # define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
41 * Use buffered writes to flash by default - they are about 32x faster than
44 #ifndef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
45 #define CFG_GEN860T_FLASH_USE_WRITE_BUFFER
49 * Max time to wait (in mS) for flash device to allocate a write buffer.
51 #ifndef CFG_FLASH_ALLOC_BUFFER_TOUT
52 #define CFG_FLASH_ALLOC_BUFFER_TOUT 100
56 * These functions support a single Intel StrataFlash device (28F128J3A)
57 * in byte mode only!. The flash routines are very basic and simple
58 * since there isn't really any remapping necessary.
62 * Intel SCS (Scalable Command Set) command definitions
63 * (taken from 28F128J3A datasheet)
65 #define SCS_READ_CMD 0xff
66 #define SCS_READ_ID_CMD 0x90
67 #define SCS_QUERY_CMD 0x98
68 #define SCS_READ_STATUS_CMD 0x70
69 #define SCS_CLEAR_STATUS_CMD 0x50
70 #define SCS_WRITE_BUF_CMD 0xe8
71 #define SCS_PROGRAM_CMD 0x40
72 #define SCS_BLOCK_ERASE_CMD 0x20
73 #define SCS_BLOCK_ERASE_RESUME_CMD 0xd0
74 #define SCS_PROGRAM_RESUME_CMD 0xd0
75 #define SCS_BLOCK_ERASE_SUSPEND_CMD 0xb0
76 #define SCS_SET_BLOCK_LOCK_CMD 0x60
77 #define SCS_CLR_BLOCK_LOCK_CMD 0x60
80 * SCS status/extended status register bit definitions
85 /*---------------------------------------------------------------------*/
91 #define PRINTF(fmt,args...) printf(fmt ,##args)
93 #define PRINTF(fmt,args...)
95 /*---------------------------------------------------------------------*/
97 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
];
99 /*-----------------------------------------------------------------------
102 static ulong
flash_get_size (vu_char
*addr
, flash_info_t
*info
);
103 static int write_data8 (flash_info_t
*info
, ulong dest
, uchar data
);
104 static void flash_get_offsets (ulong base
, flash_info_t
*info
);
106 /*-----------------------------------------------------------------------
107 * Initialize the flash memory.
112 volatile immap_t
*immap
= (immap_t
*)CFG_IMMR
;
113 volatile memctl8xx_t
*memctl
= &immap
->im_memctl
;
114 unsigned long size_b0
;
117 for (i
= 0; i
< CFG_MAX_FLASH_BANKS
; ++i
) {
118 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
122 * The gen860t board only has one FLASH memory device, so the
123 * FLASH Bank configuration is done statically.
125 PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM
);
126 size_b0
= flash_get_size((vu_char
*)FLASH_BASE0_PRELIM
, &flash_info
[0]);
127 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
128 printf ("## Unknown FLASH on Bank 0: "
129 "ID 0x%lx, Size = 0x%08lx = %ld MB\n",
130 flash_info
[0].flash_id
,size_b0
, size_b0
<< 20);
133 PRINTF("## Before remap:\n"
134 " BR0: 0x%08x OR0: 0x%08x\n BR1: 0x%08x OR1: 0x%08x\n",
135 memctl
->memc_br0
, memctl
->memc_or0
,
136 memctl
->memc_br1
, memctl
->memc_or1
);
139 * Remap FLASH according to real size
141 memctl
->memc_or0
|= (-size_b0
& 0xFFFF8000);
142 memctl
->memc_br0
|= (CFG_FLASH_BASE
& BR_BA_MSK
);
144 PRINTF("## After remap:\n"
145 " BR0: 0x%08x OR0: 0x%08x\n", memctl
->memc_br0
, memctl
->memc_or0
);
148 * Re-do sizing to get full correct info
150 size_b0
= flash_get_size ((vu_char
*)CFG_FLASH_BASE
, &flash_info
[0]);
151 flash_get_offsets (CFG_FLASH_BASE
, &flash_info
[0]);
152 flash_info
[0].size
= size_b0
;
154 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
156 * Monitor protection is ON by default
158 flash_protect(FLAG_PROTECT_SET
,
160 CFG_MONITOR_BASE
+ monitor_flash_len
- 1,
164 #ifdef CFG_ENV_IS_IN_FLASH
166 * Environment protection ON by default
168 flash_protect(FLAG_PROTECT_SET
,
170 CFG_ENV_ADDR
+ CFG_ENV_SECT_SIZE
- 1,
174 PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0
);
179 /*-----------------------------------------------------------------------
180 * Fill in the FLASH offset table
183 flash_get_offsets (ulong base
, flash_info_t
*info
)
187 if (info
->flash_id
== FLASH_UNKNOWN
) {
191 switch (info
->flash_id
& FLASH_VENDMASK
) {
192 case FLASH_MAN_INTEL
:
193 for (i
= 0; i
< info
->sector_count
; i
++) {
194 info
->start
[i
] = base
;
200 printf ("Don't know sector offsets for FLASH"
201 " type 0x%lx\n", info
->flash_id
);
207 /*-----------------------------------------------------------------------
208 * Display FLASH device info
211 flash_print_info (flash_info_t
*info
)
215 if (info
->flash_id
== FLASH_UNKNOWN
) {
216 printf ("Missing or unknown FLASH type\n");
220 switch (info
->flash_id
& FLASH_VENDMASK
) {
221 case FLASH_MAN_INTEL
:
225 printf ("Unknown Vendor ");
229 switch (info
->flash_id
& FLASH_TYPEMASK
) {
230 case FLASH_28F128J3A
:
231 printf ("28F128J3A (128Mbit = 128K x 128)\n");
234 printf ("Unknown Chip Type\n");
238 if (info
->size
>= (1024 * 1024)) {
243 printf (" Size: %ld %cB in %d Sectors\n",
245 (i
== 20) ? 'M' : 'k',
248 printf (" Sector Start Addresses:");
249 for (i
=0; i
<info
->sector_count
; ++i
) {
254 info
->protect
[i
] ? " (RO)" : " "
262 /*-----------------------------------------------------------------------
263 * Get size and other information for a FLASH device.
264 * NOTE: The following code cannot be run from FLASH!
267 ulong
flash_get_size (vu_char
*addr
, flash_info_t
*info
)
274 * Try to read the manufacturer ID
276 addr
[0] = SCS_READ_CMD
;
277 addr
[0] = SCS_READ_ID_CMD
;
280 addr
[0] = SCS_READ_CMD
;
282 PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong
)addr
, value
[0]);
284 case (INTEL_MANUFACT
& 0xff):
285 info
->flash_id
= FLASH_MAN_INTEL
;
288 info
->flash_id
= FLASH_UNKNOWN
;
289 info
->sector_count
= 0;
297 PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong
)(&addr
[2]), value
[1]);
299 case (INTEL_ID_28F128J3A
& 0xff):
300 info
->flash_id
+= FLASH_28F128J3A
;
301 info
->sector_count
= 128;
302 info
->size
= 16 * 1024 * 1024;
306 info
->flash_id
= FLASH_UNKNOWN
;
310 if (info
->sector_count
> CFG_MAX_FLASH_SECT
) {
311 printf ("** ERROR: sector count %d > max (%d) **\n",
312 info
->sector_count
, CFG_MAX_FLASH_SECT
);
313 info
->sector_count
= CFG_MAX_FLASH_SECT
;
319 /*-----------------------------------------------------------------------
320 * Erase the specified sectors in the specified FLASH device
323 flash_erase(flash_info_t
*info
, int s_first
, int s_last
)
325 int flag
, prot
, sect
;
326 ulong start
, now
, last
;
328 if ((s_first
< 0) || (s_first
> s_last
)) {
329 if (info
->flash_id
== FLASH_UNKNOWN
) {
330 printf ("- missing\n");
332 printf ("- no sectors to erase\n");
337 if ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_INTEL
) {
338 printf ("Can erase only Intel flash types - aborted\n");
343 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
344 if (info
->protect
[sect
]) {
350 printf ("- Warning: %d protected sectors will not be erased!\n",
356 start
= get_timer (0);
360 * Start erase on unprotected sectors
362 for (sect
= s_first
; sect
<=s_last
; sect
++) {
363 if (info
->protect
[sect
] == 0) { /* not protected */
364 vu_char
*addr
= (uchar
*)(info
->start
[sect
]);
368 * Disable interrupts which might cause a timeout
370 flag
= disable_interrupts();
372 *addr
= SCS_CLEAR_STATUS_CMD
;
373 *addr
= SCS_BLOCK_ERASE_CMD
;
374 *addr
= SCS_BLOCK_ERASE_RESUME_CMD
;
377 * Re-enable interrupts if necessary
383 * Wait at least 80us - let's wait 1 ms
387 while (((status
= *addr
) & SCS_SR7
) != SCS_SR7
) {
388 if ((now
=get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
389 printf ("Timeout\n");
390 *addr
= SCS_BLOCK_ERASE_SUSPEND_CMD
;
391 *addr
= SCS_READ_CMD
;
396 * Show that we're waiting
398 if ((now
- last
) > 1000) { /* 1 second */
403 *addr
= SCS_READ_CMD
;
411 #ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
413 * Allocate a flash buffer, fill it with data and write it to the flash.
415 * 1 - Timeout on buffer request
417 * NOTE: After the last call to this function, WSM status needs to be checked!
420 write_flash_buffer8(flash_info_t
*info_p
, vu_char
*src_p
, vu_char
*dest_p
,
423 vu_char
*block_addr_p
= NULL
;
424 vu_char
*start_addr_p
= NULL
;
425 ulong blocksize
= info_p
->size
/ (ulong
)info_p
->sector_count
;
428 uint time
= get_timer(0);
430 PRINTF("%s:%d: src: 0x%p dest: 0x%p count: %d\n",
431 __FUNCTION__
, __LINE__
, src_p
, dest_p
, count
);
434 * What block are we in? We already know that the source address is
435 * in the flash address range, but we also can't cross a block boundary.
436 * We assume that the block does not cross a boundary (we'll check before
437 * calling this function).
439 for (i
= 0; i
< info_p
->sector_count
; ++i
) {
440 if ( ((ulong
)dest_p
>= info_p
->start
[i
]) &&
441 ((ulong
)dest_p
< (info_p
->start
[i
] + blocksize
)) ) {
442 PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
443 __FUNCTION__
, __LINE__
, dest_p
, i
, info_p
->start
[i
]);
444 block_addr_p
= (vu_char
*)info_p
->start
[i
];
452 *block_addr_p
= SCS_WRITE_BUF_CMD
;
453 while ((*block_addr_p
& SCS_XSR7
) != SCS_XSR7
) {
454 if (get_timer(time
) > CFG_FLASH_ALLOC_BUFFER_TOUT
) {
455 PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
456 __FUNCTION__
, __LINE__
, block_addr_p
,
457 CFG_FLASH_ALLOC_BUFFER_TOUT
);
460 *block_addr_p
= SCS_WRITE_BUF_CMD
;
464 * Fill the buffer with data
466 start_addr_p
= dest_p
;
467 *block_addr_p
= count
- 1; /* flash device wants count - 1 */
468 PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
469 __FUNCTION__
, __LINE__
, block_addr_p
);
470 for (i
= 0; i
< count
; i
++) {
471 *start_addr_p
++ = *src_p
++;
475 * Flush buffer to flash
477 *block_addr_p
= SCS_PROGRAM_RESUME_CMD
;
480 while ((*block_addr_p
& SCS_SR7
) != SCS_SR7
) {
481 if (get_timer(time
) > CFG_FLASH_WRITE_TOUT
) {
482 PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
483 __FUNCTION__
, __LINE__
, block_addr_p
, CFG_FLASH_WRITE_TOUT
);
494 /*-----------------------------------------------------------------------
495 * Copy memory to flash, returns:
498 * 2 - Flash not erased
499 * 4 - Flash not identified
502 write_buff(flash_info_t
*info_p
, uchar
*src_p
, ulong addr
, ulong count
)
505 #ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
506 #define FLASH_WRITE_BUF_SIZE 0x00000020 /* 32 bytes */
516 PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
517 __FUNCTION__
, __LINE__
, (ulong
)src_p
, addr
, (uint
)count
, count
);
519 if (info_p
->flash_id
== FLASH_UNKNOWN
) {
523 #ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
528 * For maximum performance, we want to align the start address to
529 * the beginning of a write buffer boundary (i.e. A4-A0 of the
530 * start address = 0). See how many bytes are required to get to a
531 * write-buffer-aligned address. If that number is non-zero, do
532 * non buffered writes of the non-aligned data. By doing non-buffered
533 * writes, we avoid the problem of crossing a block (sector) boundary
534 * with buffered writes.
536 buf_count
= FLASH_WRITE_BUF_SIZE
- (addr
& (FLASH_WRITE_BUF_SIZE
- 1));
537 if (buf_count
== FLASH_WRITE_BUF_SIZE
) { /* already on a boundary */
540 if (buf_count
> count
) { /* not a full buffers worth of data to write */
545 PRINTF("%s:%d: Write buffer alignment count = %ld\n",
546 __FUNCTION__
, __LINE__
, buf_count
);
547 while (buf_count
-- >= 1) {
548 if ((rc
= write_data8(info_p
, (ulong
)dp
++, *sp
++)) != 0) {
553 PRINTF("%s:%d: count = %ld\n", __FUNCTION__
, __LINE__
, count
);
554 if (count
== 0) { /* all done */
555 PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
556 __FUNCTION__
, __LINE__
, FLASH_WRITE_BUF_SIZE
);
561 * Now that we are write buffer aligned, write full or partial buffers.
562 * The fact that we are write buffer aligned automatically avoids
563 * crossing a block address during a write buffer operation.
565 bufs
= count
/ FLASH_WRITE_BUF_SIZE
;
566 PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__
, __LINE__
,
569 rc
= write_flash_buffer8(info_p
, sp
, dp
, FLASH_WRITE_BUF_SIZE
);
571 PRINTF("%s:%d: ** Error writing buf %d\n",
572 __FUNCTION__
, __LINE__
, bufs
);
576 sp
+= FLASH_WRITE_BUF_SIZE
;
577 dp
+= FLASH_WRITE_BUF_SIZE
;
583 i
= count
% FLASH_WRITE_BUF_SIZE
;
584 PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__
, __LINE__
, i
, i
);
586 rc
= write_flash_buffer8(info_p
, sp
, dp
, i
);
589 sp
= (vu_char
*)info_p
->start
[0];
595 while (count
-- >= 1) {
596 if((rc
= write_data8(info_p
, wp
++, *src_p
++)) != 0)
604 /*-----------------------------------------------------------------------
605 * Write a byte to Flash, returns:
608 * 2 - Flash not erased
611 write_data8 (flash_info_t
*info
, ulong dest
, uchar data
)
613 vu_char
*addr
= (vu_char
*)dest
;
618 /* Check if Flash is (sufficiently) erased */
619 if ((*addr
& data
) != data
) {
622 /* Disable interrupts which might cause a timeout here */
623 flag
= disable_interrupts();
625 *addr
= SCS_PROGRAM_CMD
;
628 /* re-enable interrupts if necessary */
632 start
= get_timer (0);
634 while (((status
= *addr
) & SCS_SR7
) != SCS_SR7
) {
635 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
636 *addr
= SCS_READ_CMD
;
640 *addr
= SCS_READ_CMD
;
644 /* vim: set ts=4 sw=4 tw=78: */