3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 * Keith Outwater, keith_outwater@mvsi.com
6 * SPDX-License-Identifier: GPL-2.0+
12 #if defined(CONFIG_ENV_IS_IN_FLASH)
13 # ifndef CONFIG_ENV_ADDR
14 # define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
16 # ifndef CONFIG_ENV_SIZE
17 # define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
19 # ifndef CONFIG_ENV_SECT_SIZE
20 # define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
25 * Use buffered writes to flash by default - they are about 32x faster than
28 #ifndef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
29 #define CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
33 * Max time to wait (in mS) for flash device to allocate a write buffer.
35 #ifndef CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT
36 #define CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT 100
40 * These functions support a single Intel StrataFlash device (28F128J3A)
41 * in byte mode only!. The flash routines are very basic and simple
42 * since there isn't really any remapping necessary.
46 * Intel SCS (Scalable Command Set) command definitions
47 * (taken from 28F128J3A datasheet)
49 #define SCS_READ_CMD 0xff
50 #define SCS_READ_ID_CMD 0x90
51 #define SCS_QUERY_CMD 0x98
52 #define SCS_READ_STATUS_CMD 0x70
53 #define SCS_CLEAR_STATUS_CMD 0x50
54 #define SCS_WRITE_BUF_CMD 0xe8
55 #define SCS_PROGRAM_CMD 0x40
56 #define SCS_BLOCK_ERASE_CMD 0x20
57 #define SCS_BLOCK_ERASE_RESUME_CMD 0xd0
58 #define SCS_PROGRAM_RESUME_CMD 0xd0
59 #define SCS_BLOCK_ERASE_SUSPEND_CMD 0xb0
60 #define SCS_SET_BLOCK_LOCK_CMD 0x60
61 #define SCS_CLR_BLOCK_LOCK_CMD 0x60
64 * SCS status/extended status register bit definitions
69 /*---------------------------------------------------------------------*/
75 #define PRINTF(fmt,args...) printf(fmt ,##args)
77 #define PRINTF(fmt,args...)
79 /*---------------------------------------------------------------------*/
81 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
];
83 /*-----------------------------------------------------------------------
86 static ulong
flash_get_size (vu_char
*addr
, flash_info_t
*info
);
87 static int write_data8 (flash_info_t
*info
, ulong dest
, uchar data
);
88 static void flash_get_offsets (ulong base
, flash_info_t
*info
);
90 /*-----------------------------------------------------------------------
91 * Initialize the flash memory.
96 volatile immap_t
*immap
= (immap_t
*)CONFIG_SYS_IMMR
;
97 volatile memctl8xx_t
*memctl
= &immap
->im_memctl
;
98 unsigned long size_b0
;
101 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; ++i
) {
102 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
106 * The gen860t board only has one FLASH memory device, so the
107 * FLASH Bank configuration is done statically.
109 PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM
);
110 size_b0
= flash_get_size((vu_char
*)FLASH_BASE0_PRELIM
, &flash_info
[0]);
111 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
112 printf ("## Unknown FLASH on Bank 0: "
113 "ID 0x%lx, Size = 0x%08lx = %ld MB\n",
114 flash_info
[0].flash_id
,size_b0
, size_b0
<< 20);
117 PRINTF("## Before remap:\n"
118 " BR0: 0x%08x OR0: 0x%08x\n BR1: 0x%08x OR1: 0x%08x\n",
119 memctl
->memc_br0
, memctl
->memc_or0
,
120 memctl
->memc_br1
, memctl
->memc_or1
);
123 * Remap FLASH according to real size
125 memctl
->memc_or0
|= (-size_b0
& 0xFFFF8000);
126 memctl
->memc_br0
|= (CONFIG_SYS_FLASH_BASE
& BR_BA_MSK
);
128 PRINTF("## After remap:\n"
129 " BR0: 0x%08x OR0: 0x%08x\n", memctl
->memc_br0
, memctl
->memc_or0
);
132 * Re-do sizing to get full correct info
134 size_b0
= flash_get_size ((vu_char
*)CONFIG_SYS_FLASH_BASE
, &flash_info
[0]);
135 flash_get_offsets (CONFIG_SYS_FLASH_BASE
, &flash_info
[0]);
136 flash_info
[0].size
= size_b0
;
138 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
140 * Monitor protection is ON by default
142 flash_protect(FLAG_PROTECT_SET
,
143 CONFIG_SYS_MONITOR_BASE
,
144 CONFIG_SYS_MONITOR_BASE
+ monitor_flash_len
- 1,
148 #ifdef CONFIG_ENV_IS_IN_FLASH
150 * Environment protection ON by default
152 flash_protect(FLAG_PROTECT_SET
,
154 CONFIG_ENV_ADDR
+ CONFIG_ENV_SECT_SIZE
- 1,
158 PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0
);
163 /*-----------------------------------------------------------------------
164 * Fill in the FLASH offset table
167 flash_get_offsets (ulong base
, flash_info_t
*info
)
171 if (info
->flash_id
== FLASH_UNKNOWN
) {
175 switch (info
->flash_id
& FLASH_VENDMASK
) {
176 case FLASH_MAN_INTEL
:
177 for (i
= 0; i
< info
->sector_count
; i
++) {
178 info
->start
[i
] = base
;
184 printf ("Don't know sector offsets for FLASH"
185 " type 0x%lx\n", info
->flash_id
);
191 /*-----------------------------------------------------------------------
192 * Display FLASH device info
195 flash_print_info (flash_info_t
*info
)
199 if (info
->flash_id
== FLASH_UNKNOWN
) {
200 printf ("Missing or unknown FLASH type\n");
204 switch (info
->flash_id
& FLASH_VENDMASK
) {
205 case FLASH_MAN_INTEL
:
209 printf ("Unknown Vendor ");
213 switch (info
->flash_id
& FLASH_TYPEMASK
) {
214 case FLASH_28F128J3A
:
215 printf ("28F128J3A (128Mbit = 128K x 128)\n");
218 printf ("Unknown Chip Type\n");
222 if (info
->size
>= (1024 * 1024)) {
227 printf (" Size: %ld %cB in %d Sectors\n",
229 (i
== 20) ? 'M' : 'k',
232 printf (" Sector Start Addresses:");
233 for (i
=0; i
<info
->sector_count
; ++i
) {
238 info
->protect
[i
] ? " (RO)" : " "
246 /*-----------------------------------------------------------------------
247 * Get size and other information for a FLASH device.
248 * NOTE: The following code cannot be run from FLASH!
251 ulong
flash_get_size (vu_char
*addr
, flash_info_t
*info
)
258 * Try to read the manufacturer ID
260 addr
[0] = SCS_READ_CMD
;
261 addr
[0] = SCS_READ_ID_CMD
;
264 addr
[0] = SCS_READ_CMD
;
266 PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong
)addr
, value
[0]);
268 case (INTEL_MANUFACT
& 0xff):
269 info
->flash_id
= FLASH_MAN_INTEL
;
272 info
->flash_id
= FLASH_UNKNOWN
;
273 info
->sector_count
= 0;
281 PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong
)(&addr
[2]), value
[1]);
283 case (INTEL_ID_28F128J3A
& 0xff):
284 info
->flash_id
+= FLASH_28F128J3A
;
285 info
->sector_count
= 128;
286 info
->size
= 16 * 1024 * 1024;
290 info
->flash_id
= FLASH_UNKNOWN
;
294 if (info
->sector_count
> CONFIG_SYS_MAX_FLASH_SECT
) {
295 printf ("** ERROR: sector count %d > max (%d) **\n",
296 info
->sector_count
, CONFIG_SYS_MAX_FLASH_SECT
);
297 info
->sector_count
= CONFIG_SYS_MAX_FLASH_SECT
;
303 /*-----------------------------------------------------------------------
304 * Erase the specified sectors in the specified FLASH device
307 flash_erase(flash_info_t
*info
, int s_first
, int s_last
)
309 int flag
, prot
, sect
;
310 ulong start
, now
, last
;
312 if ((s_first
< 0) || (s_first
> s_last
)) {
313 if (info
->flash_id
== FLASH_UNKNOWN
) {
314 printf ("- missing\n");
316 printf ("- no sectors to erase\n");
321 if ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_INTEL
) {
322 printf ("Can erase only Intel flash types - aborted\n");
327 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
328 if (info
->protect
[sect
]) {
334 printf ("- Warning: %d protected sectors will not be erased!\n",
340 start
= get_timer (0);
344 * Start erase on unprotected sectors
346 for (sect
= s_first
; sect
<=s_last
; sect
++) {
347 if (info
->protect
[sect
] == 0) { /* not protected */
348 vu_char
*addr
= (uchar
*)(info
->start
[sect
]);
352 * Disable interrupts which might cause a timeout
354 flag
= disable_interrupts();
356 *addr
= SCS_CLEAR_STATUS_CMD
;
357 *addr
= SCS_BLOCK_ERASE_CMD
;
358 *addr
= SCS_BLOCK_ERASE_RESUME_CMD
;
361 * Re-enable interrupts if necessary
367 * Wait at least 80us - let's wait 1 ms
371 while (((status
= *addr
) & SCS_SR7
) != SCS_SR7
) {
372 if ((now
=get_timer(start
)) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
373 printf ("Timeout\n");
374 *addr
= SCS_BLOCK_ERASE_SUSPEND_CMD
;
375 *addr
= SCS_READ_CMD
;
380 * Show that we're waiting
382 if ((now
- last
) > 1000) { /* 1 second */
387 *addr
= SCS_READ_CMD
;
395 #ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
397 * Allocate a flash buffer, fill it with data and write it to the flash.
399 * 1 - Timeout on buffer request
401 * NOTE: After the last call to this function, WSM status needs to be checked!
404 write_flash_buffer8(flash_info_t
*info_p
, vu_char
*src_p
, vu_char
*dest_p
,
407 vu_char
*block_addr_p
= NULL
;
408 vu_char
*start_addr_p
= NULL
;
409 ulong blocksize
= info_p
->size
/ (ulong
)info_p
->sector_count
;
412 uint time
= get_timer(0);
414 PRINTF("%s:%d: src: 0x%p dest: 0x%p count: %d\n",
415 __FUNCTION__
, __LINE__
, src_p
, dest_p
, count
);
418 * What block are we in? We already know that the source address is
419 * in the flash address range, but we also can't cross a block boundary.
420 * We assume that the block does not cross a boundary (we'll check before
421 * calling this function).
423 for (i
= 0; i
< info_p
->sector_count
; ++i
) {
424 if ( ((ulong
)dest_p
>= info_p
->start
[i
]) &&
425 ((ulong
)dest_p
< (info_p
->start
[i
] + blocksize
)) ) {
426 PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
427 __FUNCTION__
, __LINE__
, dest_p
, i
, info_p
->start
[i
]);
428 block_addr_p
= (vu_char
*)info_p
->start
[i
];
436 *block_addr_p
= SCS_WRITE_BUF_CMD
;
437 while ((*block_addr_p
& SCS_XSR7
) != SCS_XSR7
) {
438 if (get_timer(time
) > CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT
) {
439 PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
440 __FUNCTION__
, __LINE__
, block_addr_p
,
441 CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT
);
444 *block_addr_p
= SCS_WRITE_BUF_CMD
;
448 * Fill the buffer with data
450 start_addr_p
= dest_p
;
451 *block_addr_p
= count
- 1; /* flash device wants count - 1 */
452 PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
453 __FUNCTION__
, __LINE__
, block_addr_p
);
454 for (i
= 0; i
< count
; i
++) {
455 *start_addr_p
++ = *src_p
++;
459 * Flush buffer to flash
461 *block_addr_p
= SCS_PROGRAM_RESUME_CMD
;
464 while ((*block_addr_p
& SCS_SR7
) != SCS_SR7
) {
465 if (get_timer(time
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {
466 PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
467 __FUNCTION__
, __LINE__
, block_addr_p
, CONFIG_SYS_FLASH_WRITE_TOUT
);
478 /*-----------------------------------------------------------------------
479 * Copy memory to flash, returns:
482 * 2 - Flash not erased
483 * 4 - Flash not identified
486 write_buff(flash_info_t
*info_p
, uchar
*src_p
, ulong addr
, ulong count
)
489 #ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
490 #define FLASH_WRITE_BUF_SIZE 0x00000020 /* 32 bytes */
500 PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
501 __FUNCTION__
, __LINE__
, (ulong
)src_p
, addr
, (uint
)count
, count
);
503 if (info_p
->flash_id
== FLASH_UNKNOWN
) {
507 #ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
512 * For maximum performance, we want to align the start address to
513 * the beginning of a write buffer boundary (i.e. A4-A0 of the
514 * start address = 0). See how many bytes are required to get to a
515 * write-buffer-aligned address. If that number is non-zero, do
516 * non buffered writes of the non-aligned data. By doing non-buffered
517 * writes, we avoid the problem of crossing a block (sector) boundary
518 * with buffered writes.
520 buf_count
= FLASH_WRITE_BUF_SIZE
- (addr
& (FLASH_WRITE_BUF_SIZE
- 1));
521 if (buf_count
== FLASH_WRITE_BUF_SIZE
) { /* already on a boundary */
524 if (buf_count
> count
) { /* not a full buffers worth of data to write */
529 PRINTF("%s:%d: Write buffer alignment count = %ld\n",
530 __FUNCTION__
, __LINE__
, buf_count
);
531 while (buf_count
-- >= 1) {
532 if ((rc
= write_data8(info_p
, (ulong
)dp
++, *sp
++)) != 0) {
537 PRINTF("%s:%d: count = %ld\n", __FUNCTION__
, __LINE__
, count
);
538 if (count
== 0) { /* all done */
539 PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
540 __FUNCTION__
, __LINE__
, FLASH_WRITE_BUF_SIZE
);
545 * Now that we are write buffer aligned, write full or partial buffers.
546 * The fact that we are write buffer aligned automatically avoids
547 * crossing a block address during a write buffer operation.
549 bufs
= count
/ FLASH_WRITE_BUF_SIZE
;
550 PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__
, __LINE__
,
553 rc
= write_flash_buffer8(info_p
, sp
, dp
, FLASH_WRITE_BUF_SIZE
);
555 PRINTF("%s:%d: ** Error writing buf %d\n",
556 __FUNCTION__
, __LINE__
, bufs
);
560 sp
+= FLASH_WRITE_BUF_SIZE
;
561 dp
+= FLASH_WRITE_BUF_SIZE
;
567 i
= count
% FLASH_WRITE_BUF_SIZE
;
568 PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__
, __LINE__
, i
, i
);
570 rc
= write_flash_buffer8(info_p
, sp
, dp
, i
);
573 sp
= (vu_char
*)info_p
->start
[0];
579 while (count
-- >= 1) {
580 if((rc
= write_data8(info_p
, wp
++, *src_p
++)) != 0)
588 /*-----------------------------------------------------------------------
589 * Write a byte to Flash, returns:
592 * 2 - Flash not erased
595 write_data8 (flash_info_t
*info
, ulong dest
, uchar data
)
597 vu_char
*addr
= (vu_char
*)dest
;
602 /* Check if Flash is (sufficiently) erased */
603 if ((*addr
& data
) != data
) {
606 /* Disable interrupts which might cause a timeout here */
607 flag
= disable_interrupts();
609 *addr
= SCS_PROGRAM_CMD
;
612 /* re-enable interrupts if necessary */
616 start
= get_timer (0);
618 while (((status
= *addr
) & SCS_SR7
) != SCS_SR7
) {
619 if (get_timer(start
) > CONFIG_SYS_FLASH_WRITE_TOUT
) {
620 *addr
= SCS_READ_CMD
;
624 *addr
= SCS_READ_CMD
;
628 /* vim: set ts=4 sw=4 tw=78: */