]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/oxc/flash.c
3 * Marius Groeger <mgroeger@sysgo.de>
4 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
9 * Flash Routines for STM29W320DB/STM29W800D flash chips
11 *--------------------------------------------------------------------
12 * See file CREDITS for list of people who contributed to this
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
36 /*-----------------------------------------------------------------------
40 static ulong
flash_get_size (vu_char
*addr
, flash_info_t
*info
);
41 static int write_byte (flash_info_t
*info
, ulong dest
, uchar data
);
43 /*-----------------------------------------------------------------------
46 unsigned long flash_init (void)
51 /* Init: no FLASHes known */
52 for (i
=0; i
<CFG_MAX_FLASH_BANKS
; ++i
) {
53 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
57 * We use the following trick here: since flash is cyclically
58 * mapped in the 0xFF800000-0xFFFFFFFF area, we detect the type
59 * and the size of flash using 0xFF800000 as the base address,
60 * and then call flash_get_size() again to fill flash_info.
62 size
= flash_get_size((vu_char
*)CFG_FLASH_PRELIMBASE
, &flash_info
[0]);
65 flash_get_size((vu_char
*)(-size
), &flash_info
[0]);
68 #if (CFG_MONITOR_BASE >= CFG_FLASH_PRELIMBASE)
69 /* monitor protection ON by default */
70 flash_protect(FLAG_PROTECT_SET
,
72 CFG_MONITOR_BASE
+monitor_flash_len
-1,
76 #if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
78 # define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
80 flash_protect(FLAG_PROTECT_SET
,
82 CFG_ENV_ADDR
+ CFG_ENV_SIZE
- 1,
89 /*-----------------------------------------------------------------------
91 void flash_print_info (flash_info_t
*info
)
95 if (info
->flash_id
== FLASH_UNKNOWN
) {
96 printf ("missing or unknown FLASH type\n");
100 switch (info
->flash_id
& FLASH_VENDMASK
) {
105 printf ("Unknown Vendor ");
109 switch (info
->flash_id
& FLASH_TYPEMASK
) {
111 printf ("M29W320DB (32 Mbit)\n");
114 printf ("M29W800DB (8 Mbit, bottom boot block)\n");
117 printf ("M29W800DT (8 Mbit, top boot block)\n");
120 printf ("Unknown Chip Type\n");
124 printf (" Size: %ld KB in %d Sectors\n",
125 info
->size
>> 10, info
->sector_count
);
127 printf (" Sector Start Addresses:");
128 for (i
=0; i
<info
->sector_count
; ++i
) {
133 info
->protect
[i
] ? " (RO)" : " "
141 * The following code cannot be run from FLASH!
144 static ulong
flash_get_size (vu_char
*addr
, flash_info_t
*info
)
148 ulong base
= (ulong
)addr
;
150 /* Write auto select command: read Manufacturer ID */
160 /* only support STM */
161 if ((vendor
<< 16) != FLASH_MAN_STM
) {
165 if (devid
== FLASH_STM320DB
) {
166 /* MPC8240 can address maximum 2Mb of flash, that is why the MSB
167 * lead is grounded and we can access only 2 first Mb */
168 info
->flash_id
= vendor
<< 16 | devid
;
169 info
->sector_count
= 32;
170 info
->size
= info
->sector_count
* 0x10000;
171 for (i
= 0; i
< info
->sector_count
; i
++) {
172 info
->start
[i
] = base
+ i
* 0x10000;
175 else if (devid
== FLASH_STM800DB
) {
176 info
->flash_id
= vendor
<< 16 | devid
;
177 info
->sector_count
= 19;
178 info
->size
= 0x100000;
179 info
->start
[0] = 0x0000;
180 info
->start
[1] = 0x4000;
181 info
->start
[2] = 0x6000;
182 info
->start
[3] = 0x8000;
183 for (i
= 4; i
< info
->sector_count
; i
++) {
184 info
->start
[i
] = base
+ (i
-3) * 0x10000;
187 else if (devid
== FLASH_STM800DT
) {
188 info
->flash_id
= vendor
<< 16 | devid
;
189 info
->sector_count
= 19;
190 info
->size
= 0x100000;
191 for (i
= 0; i
< info
->sector_count
-4; i
++) {
192 info
->start
[i
] = base
+ i
* 0x10000;
194 info
->start
[i
] = base
+ i
* 0x10000;
195 info
->start
[i
+1] = base
+ i
* 0x10000 + 0x8000;
196 info
->start
[i
+2] = base
+ i
* 0x10000 + 0xa000;
197 info
->start
[i
+3] = base
+ i
* 0x10000 + 0xc000;
203 /* mark all sectors as unprotected */
204 for (i
= 0; i
< info
->sector_count
; i
++) {
205 info
->protect
[i
] = 0;
208 /* Issue the reset command */
209 if (info
->flash_id
!= FLASH_UNKNOWN
) {
210 addr
[0] = 0xF0; /* reset bank */
217 /*-----------------------------------------------------------------------
220 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
222 vu_char
*addr
= (vu_char
*)(info
->start
[0]);
223 int flag
, prot
, sect
, l_sect
;
224 ulong start
, now
, last
;
226 if ((s_first
< 0) || (s_first
> s_last
)) {
227 if (info
->flash_id
== FLASH_UNKNOWN
) {
228 printf ("- missing\n");
230 printf ("- no sectors to erase\n");
236 for (sect
= s_first
; sect
<= s_last
; sect
++) {
237 if (info
->protect
[sect
]) {
243 printf ("- Warning: %d protected sectors will not be erased!\n",
251 /* Disable interrupts which might cause a timeout here */
252 flag
= disable_interrupts();
260 /* wait at least 80us - let's wait 1 ms */
263 /* Start erase on unprotected sectors */
264 for (sect
= s_first
; sect
<=s_last
; sect
++) {
265 if (info
->protect
[sect
] == 0) { /* not protected */
266 addr
= (vu_char
*)(info
->start
[sect
]);
272 /* re-enable interrupts if necessary */
276 /* wait at least 80us - let's wait 1 ms */
280 * We wait for the last triggered sector
285 start
= get_timer (0);
287 addr
= (vu_char
*)(info
->start
[l_sect
]);
288 while ((addr
[0] & 0x80) != 0x80) {
289 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
290 printf ("Timeout\n");
293 /* show that we're waiting */
294 if ((now
- last
) > 1000) { /* every second */
301 /* reset to read mode */
302 addr
= (volatile unsigned char *)info
->start
[0];
303 addr
[0] = 0xF0; /* reset bank */
309 /*-----------------------------------------------------------------------
310 * Copy memory to flash, returns:
313 * 2 - Flash not erased
316 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
321 if ((rc
= write_byte(info
, addr
, *src
)) != 0) {
332 /*-----------------------------------------------------------------------
333 * Write a byte to Flash, returns:
336 * 2 - Flash not erased
338 static int write_byte (flash_info_t
*info
, ulong dest
, uchar data
)
340 vu_char
*addr
= (vu_char
*)(info
->start
[0]);
344 /* Check if Flash is (sufficiently) erased */
345 if ((*((vu_char
*)dest
) & data
) != data
) {
348 /* Disable interrupts which might cause a timeout here */
349 flag
= disable_interrupts();
355 *((vu_char
*)dest
) = data
;
357 /* re-enable interrupts if necessary */
361 /* data polling for D7 */
362 start
= get_timer (0);
363 while ((*((vu_char
*)dest
) & 0x80) != (data
& 0x80)) {
364 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
371 /*-----------------------------------------------------------------------