]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/ip860/flash.c
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
29 #if defined(CFG_ENV_IS_IN_FLASH)
31 # define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
34 # define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
36 # ifndef CFG_ENV_SECT_SIZE
37 # define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
41 /*-----------------------------------------------------------------------
44 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
);
45 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
46 static void flash_get_offsets (ulong base
, flash_info_t
*info
);
48 /*-----------------------------------------------------------------------
51 unsigned long flash_init (void)
53 volatile immap_t
*immap
= (immap_t
*)CFG_IMMR
;
54 volatile memctl8xx_t
*memctl
= &immap
->im_memctl
;
55 volatile ip860_bcsr_t
*bcsr
= (ip860_bcsr_t
*)BCSR_BASE
;
59 /* Init: enable write,
60 * or we cannot even write flash commands
62 bcsr
->bd_ctrl
|= BD_CTRL_FLWE
;
64 for (i
=0; i
<CFG_MAX_FLASH_BANKS
; ++i
) {
65 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
68 /* Static FLASH Bank configuration here - FIXME XXX */
70 size
= flash_get_size((vu_long
*)FLASH_BASE
, &flash_info
[0]);
72 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
73 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
77 /* Remap FLASH according to real size */
78 memctl
->memc_or1
= CFG_OR_TIMING_FLASH
| (-size
& 0xFFFF8000);
79 memctl
->memc_br1
= (CFG_FLASH_BASE
& BR_BA_MSK
) |
80 (memctl
->memc_br1
& ~(BR_BA_MSK
));
82 /* Re-do sizing to get full correct info */
83 size
= flash_get_size((vu_long
*)CFG_FLASH_BASE
, &flash_info
[0]);
85 flash_get_offsets (CFG_FLASH_BASE
, &flash_info
[0]);
87 flash_info
[0].size
= size
;
89 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
90 /* monitor protection ON by default */
91 flash_protect(FLAG_PROTECT_SET
,
93 CFG_MONITOR_BASE
+monitor_flash_len
-1,
97 #ifdef CFG_ENV_IS_IN_FLASH
98 /* ENV protection ON by default */
99 flash_protect(FLAG_PROTECT_SET
,
101 CFG_ENV_ADDR
+CFG_ENV_SECT_SIZE
-1,
107 /*-----------------------------------------------------------------------
109 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
113 /* all possible flash types
114 * (28F016SV, 28F160S3, 28F320S3)
115 * have the same erase block size: 64 kB per chip,
119 /* set up sector start address table */
120 for (i
= 0; i
< info
->sector_count
; i
++) {
121 info
->start
[i
] = base
;
126 /*-----------------------------------------------------------------------
128 void flash_print_info (flash_info_t
*info
)
132 if (info
->flash_id
== FLASH_UNKNOWN
) {
133 printf ("missing or unknown FLASH type\n");
137 switch (info
->flash_id
& FLASH_VENDMASK
) {
138 case FLASH_MAN_INTEL
: printf ("Intel "); break;
139 default: printf ("Unknown Vendor "); break;
142 switch (info
->flash_id
& FLASH_TYPEMASK
) {
143 case FLASH_28F016SV
: printf ("28F016SV (16 Mbit, 32 x 64k)\n");
145 case FLASH_28F160S3
: printf ("28F160S3 (16 Mbit, 32 x 512K)\n");
147 case FLASH_28F320S3
: printf ("28F320S3 (32 Mbit, 64 x 512K)\n");
149 default: printf ("Unknown Chip Type\n");
153 printf (" Size: %ld MB in %d Sectors\n",
154 info
->size
>> 20, info
->sector_count
);
156 printf (" Sector Start Addresses:");
157 for (i
=0; i
<info
->sector_count
; ++i
) {
162 info
->protect
[i
] ? " (RO)" : " "
169 /*-----------------------------------------------------------------------
173 /*-----------------------------------------------------------------------
177 * The following code cannot be run from FLASH!
180 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
)
184 ulong base
= (ulong
)addr
;
186 /* Write "Intelligent Identifier" command: read Manufacturer ID */
191 case (MT_MANUFACT
& 0x00FF00FF): /* MT or => Intel */
192 case (INTEL_ALT_MANU
& 0x00FF00FF):
193 info
->flash_id
= FLASH_MAN_INTEL
;
196 info
->flash_id
= FLASH_UNKNOWN
;
197 info
->sector_count
= 0;
199 return (0); /* no or unknown flash */
202 value
= addr
[1]; /* device ID */
205 case (INTEL_ID_28F016S
):
206 info
->flash_id
+= FLASH_28F016SV
;
207 info
->sector_count
= 32;
208 info
->size
= 0x00400000;
209 break; /* => 2x2 MB */
211 case (INTEL_ID_28F160S3
):
212 info
->flash_id
+= FLASH_28F160S3
;
213 info
->sector_count
= 32;
214 info
->size
= 0x00400000;
215 break; /* => 2x2 MB */
217 case (INTEL_ID_28F320S3
):
218 info
->flash_id
+= FLASH_28F320S3
;
219 info
->sector_count
= 64;
220 info
->size
= 0x00800000;
221 break; /* => 2x4 MB */
224 info
->flash_id
= FLASH_UNKNOWN
;
225 return (0); /* => no or unknown flash */
229 /* set up sector start address table */
230 for (i
= 0; i
< info
->sector_count
; i
++) {
231 info
->start
[i
] = base
+ (i
* 0x00020000);
232 /* don't know how to check sector protection */
233 info
->protect
[i
] = 0;
237 * Prevent writes to uninitialized FLASH.
239 if (info
->flash_id
!= FLASH_UNKNOWN
) {
240 addr
= (vu_long
*)info
->start
[0];
242 *addr
= 0xFFFFFF; /* reset bank to read array mode */
249 /*-----------------------------------------------------------------------
252 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
254 int flag
, prot
, sect
;
255 ulong start
, now
, last
;
257 if ((s_first
< 0) || (s_first
> s_last
)) {
258 if (info
->flash_id
== FLASH_UNKNOWN
) {
259 printf ("- missing\n");
261 printf ("- no sectors to erase\n");
266 if ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_INTEL
) {
267 printf ("Can't erase unknown flash type %08lx - aborted\n",
273 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
274 if (info
->protect
[sect
]) {
280 printf ("- Warning: %d protected sectors will not be erased!\n",
286 start
= get_timer (0);
289 /* Start erase on unprotected sectors */
290 for (sect
= s_first
; sect
<=s_last
; sect
++) {
291 if (info
->protect
[sect
] == 0) { /* not protected */
292 vu_long
*addr
= (vu_long
*)(info
->start
[sect
]);
294 /* Disable interrupts which might cause a timeout here */
295 flag
= disable_interrupts();
297 /* Single Block Erase Command */
301 /* Resume Command, as per errata update */
304 /* re-enable interrupts if necessary */
308 /* wait at least 80us - let's wait 1 ms */
311 while ((*addr
& 0x00800080) != 0x00800080) {
312 if ((now
=get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
313 printf ("Timeout\n");
314 *addr
= 0xFFFFFFFF; /* reset bank */
317 /* show that we're waiting */
318 if ((now
- last
) > 1000) { /* every second */
324 /* reset to read mode */
333 /*-----------------------------------------------------------------------
334 * Copy memory to flash, returns:
337 * 2 - Flash not erased
340 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
345 wp
= (addr
& ~3); /* get lower word aligned address */
348 * handle unaligned start bytes
350 if ((l
= addr
- wp
) != 0) {
352 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
353 data
= (data
<< 8) | (*(uchar
*)cp
);
355 for (; i
<4 && cnt
>0; ++i
) {
356 data
= (data
<< 8) | *src
++;
360 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
361 data
= (data
<< 8) | (*(uchar
*)cp
);
364 if ((rc
= write_word(info
, wp
, data
)) != 0) {
371 * handle word aligned part
375 for (i
=0; i
<4; ++i
) {
376 data
= (data
<< 8) | *src
++;
378 if ((rc
= write_word(info
, wp
, data
)) != 0) {
390 * handle unaligned tail bytes
393 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
394 data
= (data
<< 8) | *src
++;
397 for (; i
<4; ++i
, ++cp
) {
398 data
= (data
<< 8) | (*(uchar
*)cp
);
401 return (write_word(info
, wp
, data
));
404 /*-----------------------------------------------------------------------
405 * Write a word to Flash, returns:
408 * 2 - Flash not erased
410 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
)
412 vu_long
*addr
= (vu_long
*)dest
;
416 /* Check if Flash is (sufficiently) erased */
417 if ((*addr
& data
) != data
) {
420 /* Disable interrupts which might cause a timeout here */
421 flag
= disable_interrupts();
429 /* re-enable interrupts if necessary */
433 /* data polling for D7 */
434 start
= get_timer (0);
436 while (((csr
= *addr
) & 0x00800080) != 0x00800080) {
437 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
442 if (csr
& 0x00400040) {
443 printf ("CSR indicates write error (%08lx) at %08lx\n", csr
, (ulong
)addr
);
447 /* Clear Status Registers Command */
449 /* Reset to read array mode */
455 /*-----------------------------------------------------------------------