]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/freescale/mpc8266ads/flash.c
aa533e4b90564c69a7c5b8e6f4f8815766d37812
2 * (C) Copyright 2000, 2001
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
6 * Add support the Sharp chips on the mpc8260ads.
7 * I started with board/ip860/flash.c and made changes I found in
8 * the MTD project by David Schleef.
10 * See file CREDITS for list of people who contributed to this
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of
16 * the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
34 #if defined(CONFIG_ENV_IS_IN_FLASH)
36 # define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
39 # define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
41 # ifndef CFG_ENV_SECT_SIZE
42 # define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
46 /*-----------------------------------------------------------------------
49 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
);
50 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
51 static int clear_block_lock_bit(vu_long
* addr
);
53 /*-----------------------------------------------------------------------
56 unsigned long flash_init (void)
58 #ifndef CONFIG_MPC8266ADS
59 volatile immap_t
*immap
= (immap_t
*)CFG_IMMR
;
60 volatile memctl8xx_t
*memctl
= &immap
->im_memctl
;
61 volatile ip860_bcsr_t
*bcsr
= (ip860_bcsr_t
*)BCSR_BASE
;
66 /* Init: enable write,
67 * or we cannot even write flash commands
69 #ifndef CONFIG_MPC8266ADS
70 bcsr
->bd_ctrl
|= BD_CTRL_FLWE
;
74 for (i
=0; i
<CFG_MAX_FLASH_BANKS
; ++i
) {
75 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
77 /* set the default sector offset */
80 /* Static FLASH Bank configuration here - FIXME XXX */
82 size
= flash_get_size((vu_long
*)FLASH_BASE
, &flash_info
[0]);
84 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
85 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
89 #ifndef CONFIG_MPC8266ADS
90 /* Remap FLASH according to real size */
91 memctl
->memc_or1
= CFG_OR_TIMING_FLASH
| (-size
& 0xFFFF8000);
92 memctl
->memc_br1
= (CFG_FLASH_BASE
& BR_BA_MSK
) |
93 (memctl
->memc_br1
& ~(BR_BA_MSK
));
95 /* Re-do sizing to get full correct info */
96 size
= flash_get_size((vu_long
*)CFG_FLASH_BASE
, &flash_info
[0]);
98 flash_info
[0].size
= size
;
100 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
101 /* monitor protection ON by default */
102 flash_protect(FLAG_PROTECT_SET
,
104 CFG_MONITOR_BASE
+monitor_flash_len
-1,
108 #ifdef CONFIG_ENV_IS_IN_FLASH
109 /* ENV protection ON by default */
110 flash_protect(FLAG_PROTECT_SET
,
112 CFG_ENV_ADDR
+CFG_ENV_SECT_SIZE
-1,
118 /*-----------------------------------------------------------------------
120 void flash_print_info (flash_info_t
*info
)
124 if (info
->flash_id
== FLASH_UNKNOWN
) {
125 printf ("missing or unknown FLASH type\n");
129 switch (info
->flash_id
& FLASH_VENDMASK
) {
130 case FLASH_MAN_INTEL
: printf ("Intel "); break;
131 case FLASH_MAN_SHARP
: printf ("Sharp "); break;
132 default: printf ("Unknown Vendor "); break;
135 switch (info
->flash_id
& FLASH_TYPEMASK
) {
136 case FLASH_28F016SV
: printf ("28F016SV (16 Mbit, 32 x 64k)\n");
138 case FLASH_28F160S3
: printf ("28F160S3 (16 Mbit, 32 x 512K)\n");
140 case FLASH_28F320S3
: printf ("28F320S3 (32 Mbit, 64 x 512K)\n");
142 case FLASH_LH28F016SCT
: printf ("28F016SC (16 Mbit, 32 x 64K)\n");
144 default: printf ("Unknown Chip Type\n");
148 printf (" Size: %ld MB in %d Sectors\n",
149 info
->size
>> 20, info
->sector_count
);
151 printf (" Sector Start Addresses:");
152 for (i
=0; i
<info
->sector_count
; ++i
) {
157 info
->protect
[i
] ? " (RO)" : " "
163 /*-----------------------------------------------------------------------
167 /*-----------------------------------------------------------------------
171 * The following code cannot be run from FLASH!
174 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
)
178 ulong base
= (ulong
)addr
;
181 /* Write "Intelligent Identifier" command: read Manufacturer ID */
184 value
= addr
[0] & 0x00FF00FF;
186 case MT_MANUFACT
: /* SHARP, MT or => Intel */
188 info
->flash_id
= FLASH_MAN_INTEL
;
191 printf("unknown manufacturer: %x\n", (unsigned int)value
);
192 info
->flash_id
= FLASH_UNKNOWN
;
193 info
->sector_count
= 0;
195 return (0); /* no or unknown flash */
198 value
= addr
[1]; /* device ID */
201 case (INTEL_ID_28F016S
):
202 info
->flash_id
+= FLASH_28F016SV
;
203 info
->sector_count
= 32;
204 info
->size
= 0x00400000;
205 sector_offset
= 0x20000;
206 break; /* => 2x2 MB */
208 case (INTEL_ID_28F160S3
):
209 info
->flash_id
+= FLASH_28F160S3
;
210 info
->sector_count
= 32;
211 info
->size
= 0x00400000;
212 sector_offset
= 0x20000;
213 break; /* => 2x2 MB */
215 case (INTEL_ID_28F320S3
):
216 info
->flash_id
+= FLASH_28F320S3
;
217 info
->sector_count
= 64;
218 info
->size
= 0x00800000;
219 sector_offset
= 0x20000;
220 break; /* => 2x4 MB */
222 case SHARP_ID_28F016SCL
:
223 case SHARP_ID_28F016SCZ
:
224 info
->flash_id
= FLASH_MAN_SHARP
| FLASH_LH28F016SCT
;
225 info
->sector_count
= 32;
226 info
->size
= 0x00800000;
227 sector_offset
= 0x40000;
228 break; /* => 4x2 MB */
232 info
->flash_id
= FLASH_UNKNOWN
;
233 return (0); /* => no or unknown flash */
237 /* set up sector start address table */
238 for (i
= 0; i
< info
->sector_count
; i
++) {
239 info
->start
[i
] = base
;
240 base
+= sector_offset
;
241 /* don't know how to check sector protection */
242 info
->protect
[i
] = 0;
246 * Prevent writes to uninitialized FLASH.
248 if (info
->flash_id
!= FLASH_UNKNOWN
) {
249 addr
= (vu_long
*)info
->start
[0];
251 *addr
= 0xFFFFFF; /* reset bank to read array mode */
258 /*-----------------------------------------------------------------------
261 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
263 int flag
, prot
, sect
;
264 ulong start
, now
, last
;
266 if ((s_first
< 0) || (s_first
> s_last
)) {
267 if (info
->flash_id
== FLASH_UNKNOWN
) {
268 printf ("- missing\n");
270 printf ("- no sectors to erase\n");
275 if ( ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_INTEL
)
276 && ((info
->flash_id
& FLASH_VENDMASK
) != FLASH_MAN_SHARP
) ) {
277 printf ("Can't erase unknown flash type %08lx - aborted\n",
283 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
284 if (info
->protect
[sect
]) {
290 printf ("- Warning: %d protected sectors will not be erased!\n",
296 /* Make Sure Block Lock Bit is not set. */
297 if(clear_block_lock_bit((vu_long
*)(info
->start
[s_first
]))){
302 /* Start erase on unprotected sectors */
303 for (sect
= s_first
; sect
<=s_last
; sect
++) {
304 if (info
->protect
[sect
] == 0) { /* not protected */
305 vu_long
*addr
= (vu_long
*)(info
->start
[sect
]);
307 last
= start
= get_timer (0);
309 /* Disable interrupts which might cause a timeout here */
310 flag
= disable_interrupts();
314 /* Clear Status Register */
316 /* Single Block Erase Command */
321 if((info
->flash_id
& FLASH_TYPEMASK
) != FLASH_LH28F016SCT
) {
322 /* Resume Command, as per errata update */
326 /* re-enable interrupts if necessary */
330 /* wait at least 80us - let's wait 1 ms */
332 while ((*addr
& 0x80808080) != 0x80808080) {
333 if(*addr
& 0x20202020){
334 printf("Error in Block Erase - Lock Bit may be set!\n");
335 printf("Status Register = 0x%X\n", (uint
)*addr
);
336 *addr
= 0xFFFFFFFF; /* reset bank */
339 if ((now
=get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
340 printf ("Timeout\n");
341 *addr
= 0xFFFFFFFF; /* reset bank */
344 /* show that we're waiting */
345 if ((now
- last
) > 1000) { /* every second */
351 /* reset to read mode */
360 /*-----------------------------------------------------------------------
361 * Copy memory to flash, returns:
364 * 2 - Flash not erased
367 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
372 wp
= (addr
& ~3); /* get lower word aligned address */
375 * handle unaligned start bytes
377 if ((l
= addr
- wp
) != 0) {
379 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
380 data
= (data
<< 8) | (*(uchar
*)cp
);
382 for (; i
<4 && cnt
>0; ++i
) {
383 data
= (data
<< 8) | *src
++;
387 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
388 data
= (data
<< 8) | (*(uchar
*)cp
);
391 if ((rc
= write_word(info
, wp
, data
)) != 0) {
398 * handle word aligned part
402 for (i
=0; i
<4; ++i
) {
403 data
= (data
<< 8) | *src
++;
405 if ((rc
= write_word(info
, wp
, data
)) != 0) {
417 * handle unaligned tail bytes
420 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
421 data
= (data
<< 8) | *src
++;
424 for (; i
<4; ++i
, ++cp
) {
425 data
= (data
<< 8) | (*(uchar
*)cp
);
428 return (write_word(info
, wp
, data
));
431 /*-----------------------------------------------------------------------
432 * Write a word to Flash, returns:
435 * 2 - Flash not erased
437 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
)
439 vu_long
*addr
= (vu_long
*)dest
;
443 /* Check if Flash is (sufficiently) erased */
444 if ((*addr
& data
) != data
) {
447 /* Disable interrupts which might cause a timeout here */
448 flag
= disable_interrupts();
456 /* re-enable interrupts if necessary */
460 /* data polling for D7 */
461 start
= get_timer (0);
463 while (((csr
= *addr
) & 0x80808080) != 0x80808080) {
464 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
469 if (csr
& 0x40404040) {
470 printf ("CSR indicates write error (%08lx) at %08lx\n", csr
, (ulong
)addr
);
474 /* Clear Status Registers Command */
476 /* Reset to read array mode */
482 /*-----------------------------------------------------------------------
483 * Clear Block Lock Bit, returns:
488 static int clear_block_lock_bit(vu_long
* addr
)
494 /* Clear Status Register */
500 start
= get_timer (0);
501 while(*addr
!= 0x80808080){
502 if ((now
=get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
503 printf ("Timeout on clearing Block Lock Bit\n");
504 *addr
= 0xFFFFFFFF; /* reset bank */