2 * (C) Copyright 2000-2004
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,
26 #include <asm/processor.h>
28 #if CFG_MAX_FLASH_BANKS != 1
29 #error "CFG_MAX_FLASH_BANKS must be 1"
31 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
33 /*-----------------------------------------------------------------------
36 static ulong flash_get_size (vu_long * addr, flash_info_t * info);
37 static int write_word (flash_info_t * info, ulong dest, ulong data);
38 static void flash_get_offsets (ulong base, flash_info_t * info);
42 #define FLASH_WORD_SIZE unsigned char
44 /*-----------------------------------------------------------------------*/
46 unsigned long flash_init (void)
48 unsigned long size_b0;
50 /* Init: no FLASHes known */
51 flash_info[0].flash_id = FLASH_UNKNOWN;
53 /* Static FLASH Bank configuration here - FIXME XXX */
55 size_b0 = flash_get_size ((vu_long *) FLASH_BASE0_PRELIM,
58 if (flash_info[0].flash_id == FLASH_UNKNOWN) {
59 printf ("## Unknown FLASH on Bank 0- Size=0x%08lx=%ld MB\n",
60 size_b0, size_b0 << 20);
65 flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]);
67 /* Monitor protection ON by default */
68 (void) flash_protect (FLAG_PROTECT_SET,
70 FLASH_BASE0_PRELIM + monitor_flash_len - 1,
72 flash_info[0].size = size_b0;
78 /*-----------------------------------------------------------------------*/
80 * This implementation assumes that the flash chips are uniform sector
81 * devices. This is true for all likely flash devices on a HCUx.
83 static void flash_get_offsets (ulong base, flash_info_t * info)
86 unsigned long sector_size = info->size / info->sector_count;
88 for (idx = 0; idx < info->sector_count; idx += 1) {
89 info->start[idx] = base + (idx * sector_size);
93 /*-----------------------------------------------------------------------*/
94 void flash_print_info (flash_info_t * info)
100 volatile unsigned long *flash;
102 if (info->flash_id == FLASH_UNKNOWN) {
103 printf ("missing or unknown FLASH type\n");
107 switch (info->flash_id & FLASH_VENDMASK) {
118 printf ("ST Micro ");
121 printf ("Unknown Vendor ");
125 /* (Reduced table of only parts expected in HCUx boards.) */
126 switch (info->flash_id) {
127 case FLASH_MAN_AMD | FLASH_AM040:
128 printf ("AM29F040 (512 Kbit, uniform sector size)\n");
130 case FLASH_MAN_STM | FLASH_AM040:
131 printf ("MM29W040W (512 Kbit, uniform sector size)\n");
134 printf ("Unknown Chip Type\n");
138 printf (" Size: %ld KB in %d Sectors\n",
139 info->size >> 10, info->sector_count);
141 printf (" Sector Start Addresses:");
142 for (i = 0; i < info->sector_count; ++i) {
144 * Check if whole sector is erased
146 if (i != (info->sector_count - 1))
147 size = info->start[i + 1] - info->start[i];
149 size = info->start[0] + info->size - info->start[i];
151 flash = (volatile unsigned long *) info->start[i];
152 size = size >> 2; /* divide by 4 for longword access */
153 for (k = 0; k < size; k++) {
154 if (*flash++ != 0xffffffff) {
162 printf (" %08lX%s%s",
164 erased ? " E" : " ", info->protect[i] ? "RO " : " "
171 /*-----------------------------------------------------------------------*/
174 * The following code cannot be run from FLASH!
176 static ulong flash_get_size (vu_long * addr, flash_info_t * info)
179 FLASH_WORD_SIZE value;
180 ulong base = (ulong) addr;
181 volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
183 /* Write auto select command: read Manufacturer ID */
185 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
187 addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
189 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00900090;
196 case (FLASH_WORD_SIZE) AMD_MANUFACT:
197 info->flash_id = FLASH_MAN_AMD;
199 case (FLASH_WORD_SIZE) FUJ_MANUFACT:
200 info->flash_id = FLASH_MAN_FUJ;
202 case (FLASH_WORD_SIZE) SST_MANUFACT:
203 info->flash_id = FLASH_MAN_SST;
205 case (FLASH_WORD_SIZE)STM_MANUFACT:
206 info->flash_id = FLASH_MAN_STM;
209 info->flash_id = FLASH_UNKNOWN;
210 info->sector_count = 0;
212 printf("Unknown flash manufacturer code: 0x%x at %p\n",
214 addr2[ADDR0] = (FLASH_WORD_SIZE) 0;
215 return (0); /* no or unknown flash */
218 value = addr2[1]; /* device ID */
221 case (FLASH_WORD_SIZE) AMD_ID_F040B:
222 info->flash_id += FLASH_AM040;
223 info->sector_count = 8;
224 info->size = 0x0080000; /* => 512 ko */
226 case (FLASH_WORD_SIZE) AMD_ID_LV040B:
227 info->flash_id += FLASH_AM040;
228 info->sector_count = 8;
229 info->size = 0x0080000; /* => 512 ko */
231 case (FLASH_WORD_SIZE)STM_ID_M29W040B: /* most likele HCU5 chip */
232 info->flash_id += FLASH_AM040;
233 info->sector_count = 8;
234 info->size = 0x0080000; /* => 512 ko */
237 info->flash_id = FLASH_UNKNOWN;
238 return (0); /* => no or unknown flash */
242 /* Calculate the sector offsets (Use HCUx Optimized code). */
243 flash_get_offsets(base, info);
245 /* check for protected sectors */
246 for (i = 0; i < info->sector_count; i++) {
247 /* read sector protection at sector address,
249 * D0 = 1 if protected
251 addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]);
252 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
253 info->protect[i] = 0;
255 info->protect[i] = addr2[2] & 1;
259 * Prevent writes to uninitialized FLASH.
261 if (info->flash_id != FLASH_UNKNOWN) {
262 addr2 = (FLASH_WORD_SIZE *) info->start[0];
263 *addr2 = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
269 int wait_for_DQ7 (flash_info_t * info, int sect)
271 ulong start, now, last;
272 volatile FLASH_WORD_SIZE *addr =
273 (FLASH_WORD_SIZE *) (info->start[sect]);
275 start = get_timer (0);
277 while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
278 (FLASH_WORD_SIZE) 0x00800080) {
279 if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
280 printf ("Timeout\n");
283 /* show that we're waiting */
284 if ((now - last) > 1000) { /* every second */
292 /*-----------------------------------------------------------------------*/
294 int flash_erase (flash_info_t * info, int s_first, int s_last)
296 volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
297 volatile FLASH_WORD_SIZE *addr2;
298 int flag, prot, sect, l_sect;
301 if ((s_first < 0) || (s_first > s_last)) {
302 if (info->flash_id == FLASH_UNKNOWN) {
303 printf ("- missing\n");
305 printf ("- no sectors to erase\n");
310 if (info->flash_id == FLASH_UNKNOWN) {
311 printf ("Can't erase unknown flash type - aborted\n");
316 for (sect = s_first; sect <= s_last; ++sect) {
317 if (info->protect[sect]) {
323 printf ("- Warning: %d protected sectors not erased!\n",
331 /* Disable interrupts which might cause a timeout here */
332 flag = disable_interrupts ();
334 /* Start erase on unprotected sectors */
335 for (sect = s_first; sect <= s_last; sect++) {
336 if (info->protect[sect] == 0) { /* not protected */
337 addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
338 printf ("Erasing sector %p\n", addr2); /* CLH */
340 if ((info->flash_id & FLASH_VENDMASK) ==
342 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
343 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
344 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
345 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
346 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
348 addr2[0] = (FLASH_WORD_SIZE) 0x00500050;
349 for (i = 0; i < 50; i++) udelay (1000);
351 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
352 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
353 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
354 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
355 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
357 addr2[0] = (FLASH_WORD_SIZE) 0x00300030;
361 * Wait for each sector to complete, it's more
362 * reliable. According to AMD Spec, you must
363 * issue all erase commands within a specified
364 * timeout. This has been seen to fail, especially
365 * if printf()s are included (for debug)!!
367 wait_for_DQ7 (info, sect);
371 /* re-enable interrupts if necessary */
373 enable_interrupts ();
375 /* wait at least 80us - let's wait 1 ms */
379 * We wait for the last triggered sector
383 wait_for_DQ7 (info, l_sect);
386 /* reset to read mode */
387 addr = (FLASH_WORD_SIZE *) info->start[0];
388 addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
394 /*-----------------------------------------------------------------------
395 * Copy memory to flash, returns:
398 * 2 - Flash not erased
401 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
406 wp = (addr & ~3); /* get lower word aligned address */
409 * handle unaligned start bytes
411 if ((l = addr - wp) != 0) {
413 for (i = 0, cp = wp; i < l; ++i, ++cp) {
414 data = (data << 8) | (*(uchar *) cp);
416 for (; i < 4 && cnt > 0; ++i) {
417 data = (data << 8) | *src++;
421 for (; cnt == 0 && i < 4; ++i, ++cp) {
422 data = (data << 8) | (*(uchar *) cp);
425 if ((rc = write_word (info, wp, data)) != 0) {
432 * handle word aligned part
436 for (i = 0; i < 4; ++i) {
437 data = (data << 8) | *src++;
439 if ((rc = write_word (info, wp, data)) != 0) {
451 * handle unaligned tail bytes
454 for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
455 data = (data << 8) | *src++;
458 for (; i < 4; ++i, ++cp) {
459 data = (data << 8) | (*(uchar *) cp);
462 return (write_word (info, wp, data));
465 /*-----------------------------------------------------------------------
466 * Write a word to Flash, returns:
469 * 2 - Flash not erased
471 static int write_word (flash_info_t * info, ulong dest, ulong data)
473 volatile FLASH_WORD_SIZE *addr2 =
474 (FLASH_WORD_SIZE *) (info->start[0]);
475 volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
476 volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
480 /* Check if Flash is (sufficiently) erased */
481 if ((*((volatile FLASH_WORD_SIZE *) dest) &
482 (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
486 for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
489 /* Disable interrupts which might cause a timeout here */
490 flag = disable_interrupts ();
492 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
493 addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
494 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
498 /* re-enable interrupts if necessary */
500 enable_interrupts ();
502 /* data polling for D7 */
503 start = get_timer (0);
504 while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
505 (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
507 if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {