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,
25 * Yoo. Jonghoon, IPone, yooth@ipone.co.kr
26 * U-Boot port on RPXlite board
28 * Some of flash control words are modified. (from 2x16bit device
30 * RPXLite board I tested has only 4 AM29LV800BB devices. Other devices
33 * (?) Does an RPXLite board which
34 * does not use AM29LV800 flash memory exist ?
41 flash_info_t flash_info
[CFG_MAX_FLASH_BANKS
]; /* info for FLASH chips */
43 /*-----------------------------------------------------------------------
46 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
);
47 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
);
48 static void flash_get_offsets (ulong base
, flash_info_t
*info
);
50 /*-----------------------------------------------------------------------
53 unsigned long flash_init (void)
55 /* volatile immap_t *immap = (immap_t *)CFG_IMMR; */
56 /* volatile memctl8xx_t *memctl = &immap->im_memctl; */
57 unsigned long size_b0
;
60 /* Init: no FLASHes known */
61 for (i
=0; i
<CFG_MAX_FLASH_BANKS
; ++i
) {
62 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
65 /* Static FLASH Bank configuration here - FIXME XXX */
67 size_b0 = flash_get_size((vu_long *)FLASH_BASE_DEBUG, &flash_info[0]);
69 if (flash_info[0].flash_id == FLASH_UNKNOWN) {
70 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
71 size_b0, size_b0<<20);
74 /* Remap FLASH according to real size */
76 memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
77 memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
79 /* Re-do sizing to get full correct info */
81 size_b0
= flash_get_size((vu_long
*)CFG_FLASH_BASE
, &flash_info
[0]);
82 flash_get_offsets (CFG_FLASH_BASE
, &flash_info
[0]);
84 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
85 /* monitor protection ON by default */
86 flash_protect(FLAG_PROTECT_SET
,
88 CFG_MONITOR_BASE
+monitor_flash_len
-1,
92 flash_info
[0].size
= size_b0
;
97 /*-----------------------------------------------------------------------
99 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
103 /* set up sector start address table */
104 if (info
->flash_id
& FLASH_BTYPE
) {
105 /* set sector offsets for bottom boot block type */
106 info
->start
[0] = base
+ 0x00000000;
107 info
->start
[1] = base
+ 0x00010000;
108 info
->start
[2] = base
+ 0x00018000;
109 info
->start
[3] = base
+ 0x00020000;
110 for (i
= 4; i
< info
->sector_count
; i
++) {
111 info
->start
[i
] = base
+ ((i
-3) * 0x00040000) ;
114 /* set sector offsets for top boot block type */
115 i
= info
->sector_count
- 1;
116 info
->start
[i
--] = base
+ info
->size
- 0x00010000;
117 info
->start
[i
--] = base
+ info
->size
- 0x00018000;
118 info
->start
[i
--] = base
+ info
->size
- 0x00020000;
119 for (; i
>= 0; i
--) {
120 info
->start
[i
] = base
+ i
* 0x00040000;
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_AMD
: printf ("AMD "); break;
139 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
140 default: printf ("Unknown Vendor "); break;
143 switch (info
->flash_id
& FLASH_TYPEMASK
) {
144 case FLASH_AM400B
: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
146 case FLASH_AM400T
: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
148 case FLASH_AM800B
: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
150 case FLASH_AM800T
: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
152 case FLASH_AM160B
: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
154 case FLASH_AM160T
: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
156 case FLASH_AM320B
: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
158 case FLASH_AM320T
: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
160 default: printf ("Unknown Chip Type\n");
164 printf (" Size: %ld MB in %d Sectors\n",
165 info
->size
>> 20, info
->sector_count
);
167 printf (" Sector Start Addresses:");
168 for (i
=0; i
<info
->sector_count
; ++i
) {
173 info
->protect
[i
] ? " (RO)" : " "
180 /*-----------------------------------------------------------------------
184 /*-----------------------------------------------------------------------
188 * The following code cannot be run from FLASH!
191 static ulong
flash_get_size (vu_long
*addr
, flash_info_t
*info
)
195 ulong base
= (ulong
)addr
;
197 /* Write auto select command: read Manufacturer ID */
198 addr
[0xAAA] = 0x00AA00AA ;
199 addr
[0x555] = 0x00550055 ;
200 addr
[0xAAA] = 0x00900090 ;
204 switch (value
& 0x00FF00FF) {
206 info
->flash_id
= FLASH_MAN_AMD
;
209 info
->flash_id
= FLASH_MAN_FUJ
;
212 info
->flash_id
= FLASH_UNKNOWN
;
213 info
->sector_count
= 0;
215 return (0); /* no or unknown flash */
218 value
= addr
[2] ; /* device ID */
220 switch (value
& 0x00FF00FF) {
221 case (AMD_ID_LV400T
& 0x00FF00FF):
222 info
->flash_id
+= FLASH_AM400T
;
223 info
->sector_count
= 11;
224 info
->size
= 0x00100000;
227 case (AMD_ID_LV400B
& 0x00FF00FF):
228 info
->flash_id
+= FLASH_AM400B
;
229 info
->sector_count
= 11;
230 info
->size
= 0x00100000;
233 case (AMD_ID_LV800T
& 0x00FF00FF):
234 info
->flash_id
+= FLASH_AM800T
;
235 info
->sector_count
= 19;
236 info
->size
= 0x00200000;
239 case (AMD_ID_LV800B
& 0x00FF00FF):
240 info
->flash_id
+= FLASH_AM800B
;
241 info
->sector_count
= 19;
242 info
->size
= 0x00400000; /*%%% Size doubled by yooth */
245 case (AMD_ID_LV160T
& 0x00FF00FF):
246 info
->flash_id
+= FLASH_AM160T
;
247 info
->sector_count
= 35;
248 info
->size
= 0x00400000;
251 case (AMD_ID_LV160B
& 0x00FF00FF):
252 info
->flash_id
+= FLASH_AM160B
;
253 info
->sector_count
= 35;
254 info
->size
= 0x00400000;
256 #if 0 /* enable when device IDs are available */
258 info
->flash_id
+= FLASH_AM320T
;
259 info
->sector_count
= 67;
260 info
->size
= 0x00800000;
264 info
->flash_id
+= FLASH_AM320B
;
265 info
->sector_count
= 67;
266 info
->size
= 0x00800000;
270 info
->flash_id
= FLASH_UNKNOWN
;
271 return (0); /* => no or unknown flash */
274 /*%%% sector start address modified */
275 /* set up sector start address table */
276 if (info
->flash_id
& FLASH_BTYPE
) {
277 /* set sector offsets for bottom boot block type */
278 info
->start
[0] = base
+ 0x00000000;
279 info
->start
[1] = base
+ 0x00010000;
280 info
->start
[2] = base
+ 0x00018000;
281 info
->start
[3] = base
+ 0x00020000;
282 for (i
= 4; i
< info
->sector_count
; i
++) {
283 info
->start
[i
] = base
+ ((i
-3) * 0x00040000) ;
286 /* set sector offsets for top boot block type */
287 i
= info
->sector_count
- 1;
288 info
->start
[i
--] = base
+ info
->size
- 0x00010000;
289 info
->start
[i
--] = base
+ info
->size
- 0x00018000;
290 info
->start
[i
--] = base
+ info
->size
- 0x00020000;
291 for (; i
>= 0; i
--) {
292 info
->start
[i
] = base
+ i
* 0x00040000;
296 /* check for protected sectors */
297 for (i
= 0; i
< info
->sector_count
; i
++) {
298 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
299 /* D0 = 1 if protected */
300 addr
= (volatile unsigned long *)(info
->start
[i
]);
301 info
->protect
[i
] = addr
[4] & 1 ;
305 * Prevent writes to uninitialized FLASH.
307 if (info
->flash_id
!= FLASH_UNKNOWN
) {
308 addr
= (volatile unsigned long *)info
->start
[0];
310 *addr
= 0xF0F0F0F0; /* reset bank */
317 /*-----------------------------------------------------------------------
320 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
322 vu_long
*addr
= (vu_long
*)(info
->start
[0]);
323 int flag
, prot
, sect
, l_sect
;
324 ulong start
, now
, last
;
326 if ((s_first
< 0) || (s_first
> s_last
)) {
327 if (info
->flash_id
== FLASH_UNKNOWN
) {
328 printf ("- missing\n");
330 printf ("- no sectors to erase\n");
335 if ((info
->flash_id
== FLASH_UNKNOWN
) ||
336 (info
->flash_id
> FLASH_AMD_COMP
)) {
337 printf ("Can't erase unknown flash type %08lx - aborted\n",
343 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
344 if (info
->protect
[sect
]) {
350 printf ("- Warning: %d protected sectors will not be erased!\n",
358 /* Disable interrupts which might cause a timeout here */
359 flag
= disable_interrupts();
361 addr
[0xAAA] = 0xAAAAAAAA;
362 addr
[0x555] = 0x55555555;
363 addr
[0xAAA] = 0x80808080;
364 addr
[0xAAA] = 0xAAAAAAAA;
365 addr
[0x555] = 0x55555555;
367 /* Start erase on unprotected sectors */
368 for (sect
= s_first
; sect
<=s_last
; sect
++) {
369 if (info
->protect
[sect
] == 0) { /* not protected */
370 addr
= (vu_long
*)(info
->start
[sect
]) ;
371 addr
[0] = 0x30303030 ;
376 /* re-enable interrupts if necessary */
380 /* wait at least 80us - let's wait 1 ms */
384 * We wait for the last triggered sector
389 start
= get_timer (0);
391 addr
= (vu_long
*)(info
->start
[l_sect
]);
392 while ((addr
[0] & 0x80808080) != 0x80808080) {
393 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
394 printf ("Timeout\n");
397 /* show that we're waiting */
398 if ((now
- last
) > 1000) { /* every second */
405 /* reset to read mode */
406 addr
= (vu_long
*)info
->start
[0];
407 addr
[0] = 0xF0F0F0F0; /* reset bank */
413 /*-----------------------------------------------------------------------
414 * Copy memory to flash, returns:
417 * 2 - Flash not erased
420 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
425 wp
= (addr
& ~3); /* get lower word aligned address */
428 * handle unaligned start bytes
430 if ((l
= addr
- wp
) != 0) {
432 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
433 data
= (data
<< 8) | (*(uchar
*)cp
);
435 for (; i
<4 && cnt
>0; ++i
) {
436 data
= (data
<< 8) | *src
++;
440 for (; cnt
==0 && i
<4; ++i
, ++cp
) {
441 data
= (data
<< 8) | (*(uchar
*)cp
);
444 if ((rc
= write_word(info
, wp
, data
)) != 0) {
451 * handle word aligned part
455 for (i
=0; i
<4; ++i
) {
456 data
= (data
<< 8) | *src
++;
458 if ((rc
= write_word(info
, wp
, data
)) != 0) {
470 * handle unaligned tail bytes
473 for (i
=0, cp
=wp
; i
<4 && cnt
>0; ++i
, ++cp
) {
474 data
= (data
<< 8) | *src
++;
477 for (; i
<4; ++i
, ++cp
) {
478 data
= (data
<< 8) | (*(uchar
*)cp
);
481 return (write_word(info
, wp
, data
));
484 /*-----------------------------------------------------------------------
485 * Write a word to Flash, returns:
488 * 2 - Flash not erased
490 static int write_word (flash_info_t
*info
, ulong dest
, ulong data
)
492 vu_long
*addr
= (vu_long
*)(info
->start
[0]);
496 /* Check if Flash is (sufficiently) erased */
497 if ((*((vu_long
*)dest
) & data
) != data
) {
500 /* Disable interrupts which might cause a timeout here */
501 flag
= disable_interrupts();
503 addr
[0xAAA] = 0xAAAAAAAA;
504 addr
[0x555] = 0x55555555;
505 addr
[0xAAA] = 0xA0A0A0A0;
507 *((vu_long
*)dest
) = data
;
509 /* re-enable interrupts if necessary */
513 /* data polling for D7 */
514 start
= get_timer (0);
515 while ((*((vu_long
*)dest
) & 0x80808080) != (data
& 0x80808080)) {
516 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
523 /*-----------------------------------------------------------------------