3 * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de)
5 * Support for the Elmeg VoVPN Gateway Module
6 * ------------------------------------------
7 * This is a signle bank flashdriver for INTEL 28F320J3, 28F640J3
8 * and 28F128J3A flashs working in 8 Bit mode.
10 * Most of this code is taken from existing u-boot source code.
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
];
32 #define FLASH_CMD_READ_ID 0x90
33 #define FLASH_CMD_READ_STATUS 0x70
34 #define FLASH_CMD_RESET 0xff
35 #define FLASH_CMD_BLOCK_ERASE 0x20
36 #define FLASH_CMD_ERASE_CONFIRM 0xd0
37 #define FLASH_CMD_CLEAR_STATUS 0x50
38 #define FLASH_CMD_SUSPEND_ERASE 0xb0
39 #define FLASH_CMD_WRITE 0x40
40 #define FLASH_CMD_WRITE_BUFF 0xe8
41 #define FLASH_CMD_PROG_RESUME 0xd0
42 #define FLASH_CMD_PROTECT 0x60
43 #define FLASH_CMD_PROTECT_SET 0x01
44 #define FLASH_CMD_PROTECT_CLEAR 0xd0
45 #define FLASH_STATUS_DONE 0x80
47 #define FLASH_WRITE_BUFFER_SIZE 32
49 #ifdef CFG_FLASH_16BIT
50 #define FLASH_WORD_SIZE unsigned short
51 #define FLASH_ID_MASK 0xffff
52 #define FLASH_CMD_ADDR_SHIFT 0
54 #define FLASH_WORD_SIZE unsigned char
55 #define FLASH_ID_MASK 0xff
56 /* A0 is not used in either 8x or 16x for READ ID */
57 #define FLASH_CMD_ADDR_SHIFT 1
62 flash_get(volatile FLASH_WORD_SIZE
*addr
, flash_info_t
*info
)
64 volatile FLASH_WORD_SIZE
*p
;
65 FLASH_WORD_SIZE value
;
68 addr
[0] = FLASH_CMD_READ_ID
;
71 value
= addr
[0 << FLASH_CMD_ADDR_SHIFT
];
73 case (INTEL_MANUFACT
& FLASH_ID_MASK
):
74 info
->flash_id
= FLASH_MAN_INTEL
;
77 info
->flash_id
= FLASH_UNKNOWN
;
78 info
->sector_count
= 0;
80 *addr
= FLASH_CMD_RESET
;
86 value
= addr
[1 << FLASH_CMD_ADDR_SHIFT
];
88 case (INTEL_ID_28F320J3A
& FLASH_ID_MASK
):
89 info
->flash_id
+= FLASH_28F320J3A
;
90 info
->sector_count
= 32;
91 info
->size
= 0x00400000;
93 case (INTEL_ID_28F640J3A
& FLASH_ID_MASK
):
94 info
->flash_id
+= FLASH_28F640J3A
;
95 info
->sector_count
= 64;
96 info
->size
= 0x00800000;
98 case (INTEL_ID_28F128J3A
& FLASH_ID_MASK
):
99 info
->flash_id
+= FLASH_28F128J3A
;
100 info
->sector_count
= 128;
101 info
->size
= 0x01000000;
104 info
->flash_id
= FLASH_UNKNOWN
;
105 info
->sector_count
= 0;
107 *addr
= FLASH_CMD_RESET
;
112 for (i
= 0; i
< info
->sector_count
; i
++) {
113 info
->start
[i
] = (unsigned long)addr
+ (i
* info
->size
/info
->sector_count
);
116 /* check protected sectors */
117 for (i
= 0; i
< info
->sector_count
; i
++) {
118 p
= (volatile FLASH_WORD_SIZE
*)(info
->start
[i
]);
119 info
->protect
[i
] = p
[2 << FLASH_CMD_ADDR_SHIFT
] & 1;
123 *addr
= FLASH_CMD_RESET
;
133 for (i
=0; i
<CFG_MAX_FLASH_BANKS
; ++i
) {
134 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
136 size
= flash_get((volatile FLASH_WORD_SIZE
*)CFG_FLASH_BASE
, &flash_info
[0]);
137 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
138 printf ("## Unknown FLASH Size=0x%08lx\n", size
);
142 /* always protect 1 sector containing the HRCW */
143 flash_protect(FLAG_PROTECT_SET
,
144 flash_info
[0].start
[0],
145 flash_info
[0].start
[1] - 1,
148 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
149 flash_protect(FLAG_PROTECT_SET
,
151 CFG_MONITOR_FLASH
+CFG_MONITOR_LEN
-1,
154 #ifdef CFG_ENV_IS_IN_FLASH
155 flash_protect(FLAG_PROTECT_SET
,
157 CFG_ENV_ADDR
+CFG_ENV_SECT_SIZE
-1,
164 flash_print_info(flash_info_t
*info
)
168 if (info
->flash_id
== FLASH_UNKNOWN
) {
169 printf ("missing or unknown FLASH type\n");
173 switch (info
->flash_id
& FLASH_VENDMASK
) {
174 case FLASH_MAN_INTEL
: printf ("INTEL "); break;
175 default: printf ("Unknown Vendor "); break;
178 switch (info
->flash_id
& FLASH_TYPEMASK
) {
179 case FLASH_28F320J3A
: printf ("28F320JA3 (32 Mbit)\n");
181 case FLASH_28F640J3A
: printf ("28F640JA3 (64 Mbit)\n");
183 case FLASH_28F128J3A
: printf ("28F128JA3 (128 Mbit)\n");
185 default: printf ("Unknown Chip Type");
189 printf (" Size: %ld MB in %d Sectors\n",
190 info
->size
>> 20, info
->sector_count
);
192 printf (" Sector Start Addresses:");
193 for (i
=0; i
<info
->sector_count
; ++i
) {
198 info
->protect
[i
] ? " (RO)" : " "
205 flash_erase(flash_info_t
*info
, int s_first
, int s_last
)
207 unsigned long start
, now
, last
;
208 int flag
, prot
, sect
;
209 volatile FLASH_WORD_SIZE
*addr
;
210 FLASH_WORD_SIZE status
;
212 if ((s_first
< 0) || (s_first
> s_last
)) {
213 if (info
->flash_id
== FLASH_UNKNOWN
) {
214 printf ("- missing\n");
216 printf ("- no sectors to erase\n");
221 if (info
->flash_id
== FLASH_UNKNOWN
) {
222 printf ("Cannot erase unknown flash - aborted\n");
227 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
228 if (info
->protect
[sect
]) {
234 printf ("- Warning: %d protected sectors will not be erased!\n", prot
);
239 start
= get_timer (0);
242 for (sect
= s_first
; sect
<=s_last
; sect
++) {
243 if (info
->protect
[sect
]) {
247 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[sect
]);
248 /* Disable interrupts which might cause a timeout here */
249 flag
= disable_interrupts();
252 printf("Erase sector %d at start addr 0x%08X", sect
, (unsigned int)info
->start
[sect
]);
255 *addr
= FLASH_CMD_CLEAR_STATUS
;
256 *addr
= FLASH_CMD_BLOCK_ERASE
;
257 *addr
= FLASH_CMD_ERASE_CONFIRM
;
259 /* re-enable interrupts if necessary */
264 /* wait at least 80us - let's wait 1 ms */
267 while (((status
= *addr
) & FLASH_STATUS_DONE
) != FLASH_STATUS_DONE
) {
268 if ((now
=get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
269 printf("Flash erase timeout at address %lx\n", info
->start
[sect
]);
270 *addr
= FLASH_CMD_SUSPEND_ERASE
;
271 *addr
= FLASH_CMD_RESET
;
275 /* show that we're waiting */
276 if ((now
- last
) > 1000) { /* every second */
281 *addr
= FLASH_CMD_RESET
;
288 write_buff2( volatile FLASH_WORD_SIZE
*dst
,
289 volatile FLASH_WORD_SIZE
*src
,
293 FLASH_WORD_SIZE status
;
296 start
= get_timer (0);
298 /* Disable interrupts which might cause a timeout here */
299 flag
= disable_interrupts();
300 dst
[0] = FLASH_CMD_WRITE_BUFF
;
301 if ((status
= *dst
) & FLASH_STATUS_DONE
) {
305 /* re-enable interrupts if necessary */
310 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
314 dst
[0] = (FLASH_WORD_SIZE
)(cnt
- 1);
315 for (i
=0; i
<cnt
; i
++) {
318 dst
[0] = FLASH_CMD_PROG_RESUME
;
328 poll_status( volatile FLASH_WORD_SIZE
*addr
)
332 start
= get_timer (0);
333 /* wait for error or finish */
335 if (*addr
== FLASH_STATUS_DONE
) {
336 if (*addr
== FLASH_STATUS_DONE
) {
340 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
341 *addr
= FLASH_CMD_RESET
;
345 *addr
= FLASH_CMD_RESET
;
350 * write_buff return values:
353 * 2 - Flash not erased
354 * 4 - Flash not identified
357 write_buff(flash_info_t
*info
, uchar
*src
, ulong udst
, ulong cnt
)
359 volatile FLASH_WORD_SIZE
*addr
, *dst
;
363 if (info
->flash_id
== FLASH_UNKNOWN
) {
367 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[0]);
368 dst
= (volatile FLASH_WORD_SIZE
*) udst
;
370 #ifdef CFG_FLASH_16BIT
374 /* Check if buffer write is possible */
375 if (cnt
> 1 && (((unsigned long)dst
& (FLASH_WRITE_BUFFER_SIZE
- 1)) == 0)) {
376 bcnt
= cnt
> FLASH_WRITE_BUFFER_SIZE
? FLASH_WRITE_BUFFER_SIZE
: cnt
;
377 /* Check if Flash is (sufficiently) erased */
378 for (i
=0; i
<bcnt
; i
++) {
379 if ((dst
[i
] & src
[i
]) != src
[i
]) {
383 if (write_buff2( dst
,src
,bcnt
) != 0) {
384 addr
[0] = FLASH_CMD_READ_STATUS
;
386 if (poll_status( dst
) != 0) {
395 /* Check if Flash is (sufficiently) erased */
396 if ((*dst
& *src
) != *src
) {
400 /* Disable interrupts which might cause a timeout here */
401 flag
= disable_interrupts();
402 addr
[0] = FLASH_CMD_ERASE_CONFIRM
;
403 addr
[0] = FLASH_CMD_WRITE
;
405 /* re-enable interrupts if necessary */
410 if (poll_status( dst
) != 0) {
420 flash_real_protect(flash_info_t
*info
, long sector
, int prot
)
422 volatile FLASH_WORD_SIZE
*addr
;
425 addr
= (volatile FLASH_WORD_SIZE
*)(info
->start
[sector
]);
426 *addr
= FLASH_CMD_CLEAR_STATUS
;
427 *addr
= FLASH_CMD_PROTECT
;
430 *addr
= FLASH_CMD_PROTECT_SET
;
432 *addr
= FLASH_CMD_PROTECT_CLEAR
;
435 /* wait for error or finish */
436 start
= get_timer (0);
437 while(!(addr
[0] & FLASH_STATUS_DONE
)){
438 if (get_timer(start
) > CFG_FLASH_ERASE_TOUT
) {
439 printf("Flash protect timeout at address %lx\n", info
->start
[sector
]);
440 addr
[0] = FLASH_CMD_RESET
;
445 /* Set software protect flag */
446 info
->protect
[sector
] = prot
;
447 *addr
= FLASH_CMD_RESET
;