3 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4 * Marius Groeger <mgroeger@sysgo.de>
6 * (C) Copyright 2005 Rowel Atienza <rowel@diwalabs.com>
7 * Flash driver for armadillo board HT1070
9 * See file CREDITS for list of people who contributed to this
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 #define FLASH_BANK_SIZE 0x400000
32 /*value used by hermit is 0x200*/
33 /*document says sector size is either 64k in low mem reg and 8k in high mem reg*/
34 #define MAIN_SECT_SIZE 0x10000
36 #define UNALIGNED_MASK (3)
37 #define FL_WORD(addr) (*(volatile unsigned short*)(addr))
38 #define FLASH_TIMEOUT 20000000
40 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
];
42 /*-----------------------------------------------------------------------
45 ulong
flash_init (void)
50 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; i
++) {
53 flash_info
[i
].flash_id
= (FUJ_MANUFACT
& FLASH_VENDMASK
);
54 /*(INTEL_ID_28F128J3 & FLASH_TYPEMASK); */
55 flash_info
[i
].size
= FLASH_BANK_SIZE
;
56 flash_info
[i
].sector_count
= CONFIG_SYS_MAX_FLASH_SECT
;
57 memset (flash_info
[i
].protect
, 0, CONFIG_SYS_MAX_FLASH_SECT
);
59 flashbase
= PHYS_FLASH_1
;
61 panic ("configured too many flash banks!\n");
62 for (j
= 0; j
< flash_info
[i
].sector_count
; j
++) {
63 flash_info
[i
].start
[j
] =
64 flashbase
+ j
* MAIN_SECT_SIZE
;
66 size
+= flash_info
[i
].size
;
69 /* Protect monitor and environment sectors
71 flash_protect (FLAG_PROTECT_SET
,
72 CONFIG_SYS_FLASH_BASE
,
73 CONFIG_SYS_FLASH_BASE
+ monitor_flash_len
- 1,
76 flash_protect (FLAG_PROTECT_SET
,
78 CONFIG_ENV_ADDR
+ CONFIG_ENV_SIZE
- 1, &flash_info
[0]);
83 /*-----------------------------------------------------------------------
85 void flash_print_info (flash_info_t
* info
)
89 switch (info
->flash_id
& FLASH_VENDMASK
) {
90 case (FUJ_MANUFACT
& FLASH_VENDMASK
):
94 printf ("Unknown Vendor ");
98 switch (info->flash_id & FLASH_TYPEMASK) {
99 case (INTEL_ID_28F128J3 & FLASH_TYPEMASK):
100 printf ("28F128J3 (128Mbit)\n");
103 printf ("Unknown Chip Type\n");
108 printf (" Size: %ld MB in %d Sectors\n",
109 info
->size
>> 20, info
->sector_count
);
111 printf (" Sector Start Addresses:");
112 for (i
= 0; i
< info
->sector_count
; i
++) {
116 printf (" %08lX%s", info
->start
[i
],
117 info
->protect
[i
] ? " (RO)" : " ");
127 * * Loop until both write state machines complete.
129 static unsigned short flash_status_wait (unsigned long addr
,
130 unsigned short value
)
132 unsigned short status
;
133 long timeout
= FLASH_TIMEOUT
;
135 while (((status
= (FL_WORD (addr
))) != value
) && timeout
> 0) {
142 * Loop until the Write State machine is ready, then do a full error
143 * check. Clear status and leave the flash in Read Array mode; return
144 * 0 for no error, -1 for error.
146 static int flash_status_full_check (unsigned long addr
, unsigned short value1
,
147 unsigned short value2
)
149 unsigned short status1
, status2
;
151 status1
= flash_status_wait (addr
, value1
);
152 status2
= flash_status_wait (addr
+ 2, value2
);
153 return (status1
!= value1
|| status2
!= value2
) ? -1 : 0;
156 /*-----------------------------------------------------------------------
159 int flash_erase (flash_info_t
* info
, int s_first
, int s_last
)
161 int flag
, prot
, sect
;
166 if ((info
->flash_id
& FLASH_VENDMASK
) !=
167 (FUJ_MANUFACT
& FLASH_VENDMASK
)) {
168 return ERR_UNKNOWN_FLASH_VENDOR
;
172 for (sect
= s_first
; sect
<= s_last
; ++sect
) {
173 if (info
->protect
[sect
]) {
178 return ERR_PROTECTED
;
181 * Disable interrupts which might cause a timeout
182 * here. Remember that our exception vectors are
183 * at address 0 in the flash, and we don't want a
184 * (ticker) exception to happen while the flash
185 * chip is in programming mode.
187 flag
= disable_interrupts ();
189 printf ("Erasing %d sectors starting at sector %2d.\n"
190 "This make take some time ... ",
191 s_last
- s_first
, sect
);
192 /* Start erase on unprotected sectors */
193 for (sect
= s_first
; sect
<= s_last
&& !ctrlc (); sect
++) {
194 /* ARM simple, non interrupt dependent timer */
195 reset_timer_masked ();
197 if (info
->protect
[sect
] == 0) { /* not protected */
199 addr
= sect
* MAIN_SECT_SIZE
;
200 addr
&= ~(unsigned long) UNALIGNED_MASK
; /* word align */
201 base
= addr
& 0xF0000000;
203 FL_WORD (base
+ (0x555 << 1)) = 0xAA;
204 FL_WORD (base
+ (0x2AA << 1)) = 0x55;
205 FL_WORD (base
+ (0x555 << 1)) = 0x80;
206 FL_WORD (base
+ (0x555 << 1)) = 0xAA;
207 FL_WORD (base
+ (0x2AA << 1)) = 0x55;
208 FL_WORD (addr
) = 0x30;
209 if (flash_status_full_check (addr
, 0xFFFF, 0xFFFF))
210 return ERR_PROTECTED
;
213 printf ("\nDone.\n");
215 printf ("User Interrupt!\n");
217 /* allow flash to settle - wait 10 ms */
218 udelay_masked (10000);
221 enable_interrupts ();
227 /*-----------------------------------------------------------------------
228 * Copy memory to flash
231 static int write_word (flash_info_t
* info
, ulong dest
, ushort data
)
236 /* Check if Flash is (sufficiently) erased
238 if ((FL_WORD (dest
) & data
) != data
)
239 return ERR_NOT_ERASED
;
241 /*if(dest & UNALIGNED_MASK) return ERR_ALIGN; */
244 * Disable interrupts which might cause a timeout
245 * here. Remember that our exception vectors are
246 * at address 0 in the flash, and we don't want a
247 * (ticker) exception to happen while the flash
248 * chip is in programming mode.
250 flag
= disable_interrupts ();
252 /* arm simple, non interrupt dependent timer */
253 reset_timer_masked ();
255 base
= dest
& 0xF0000000;
256 FL_WORD (base
+ (0x555 << 1)) = 0xAA;
257 FL_WORD (base
+ (0x2AA << 1)) = 0x55;
258 FL_WORD (base
+ (0x555 << 1)) = 0xA0;
259 FL_WORD (dest
) = data
;
260 /*printf("writing 0x%p = 0x%x\n",dest,data); */
261 if (flash_status_wait (dest
, data
) != data
)
262 return ERR_PROG_ERROR
;
265 enable_interrupts ();
270 /*-----------------------------------------------------------------------
271 * Copy memory to flash.
274 int write_buff (flash_info_t
* info
, uchar
* src
, ulong addr
, ulong cnt
)
281 wp
= (addr
& ~1); /* get lower word aligned address */
282 printf ("Writing %lu short data to 0x%lx from 0x%p.\n ", cnt
, wp
, src
);
285 * handle unaligned start bytes
287 if ((l
= addr
- wp
) != 0) {
289 for (i
= 0, cp
= wp
; i
< l
; ++i
, ++cp
) {
290 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
292 for (; i
< 2 && cnt
> 0; ++i
) {
293 data
= (data
>> 8) | (*src
++ << 8);
297 for (; cnt
== 0 && i
< 2; ++i
, ++cp
) {
298 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
301 if ((rc
= write_word (info
, wp
, data
)) != 0) {
308 * handle word aligned part
311 data
= *((vu_short
*) src
);
312 if ((rc
= write_word (info
, wp
, data
)) != 0) {
321 printf ("\nDone.\n");
326 * handle unaligned tail bytes
329 for (i
= 0, cp
= wp
; i
< 2 && cnt
> 0; ++i
, ++cp
) {
330 data
= (data
>> 8) | (*src
++ << 8);
333 for (; i
< 2; ++i
, ++cp
) {
334 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
337 return write_word (info
, wp
, data
);