]> git.ipfire.org Git - thirdparty/u-boot.git/blob - board/ocotea/flash.c
f44984a0e0ef70137c682bab415b5d0b25edfee0
[thirdparty/u-boot.git] / board / ocotea / flash.c
1 /*
2 * (C) Copyright 2004
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * (C) Copyright 2002 Jun Gu <jung@artesyncp.com>
6 * Add support for Am29F016D and dynamic switch setting.
7 *
8 * See file CREDITS for list of people who contributed to this
9 * project.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 * MA 02111-1307 USA
25 */
26
27 /*
28 * Modified 4/5/2001
29 * Wait for completion of each sector erase command issued
30 * 4/5/2001
31 * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
32 */
33
34 #include <common.h>
35 #include <ppc4xx.h>
36 #include <asm/processor.h>
37
38 #undef DEBUG
39
40 #ifdef DEBUG
41 #define DEBUGF(x...) printf(x)
42 #else
43 #define DEBUGF(x...)
44 #endif /* DEBUG */
45
46 #define BOOT_SMALL_FLASH 32 /* 00100000 */
47 #define FLASH_ONBD_N 2 /* 00000010 */
48 #define FLASH_SRAM_SEL 1 /* 00000001 */
49
50 #define BOOT_SMALL_FLASH_VAL 4
51 #define FLASH_ONBD_N_VAL 2
52 #define FLASH_SRAM_SEL_VAL 1
53
54
55 flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
56
57 static unsigned long flash_addr_table[8][CFG_MAX_FLASH_BANKS] = {
58 {0xFF800000, 0xFF900000, 0xFFC00000}, /* 0:000: configuraton 4 */
59 {0xFF900000, 0xFF800000, 0xFFC00000}, /* 1:001: configuraton 3 */
60 {0x00000000, 0x00000000, 0x00000000}, /* 2:010: configuraton 8 */
61 {0x00000000, 0x00000000, 0x00000000}, /* 3:011: configuraton 7 */
62 {0xFFE00000, 0xFFF00000, 0xFF800000}, /* 4:100: configuraton 2 */
63 {0xFFF00000, 0xFFF80000, 0xFF800000}, /* 5:101: configuraton 1 */
64 {0x00000000, 0x00000000, 0x00000000}, /* 6:110: configuraton 6 */
65 {0x00000000, 0x00000000, 0x00000000} /* 7:111: configuraton 5 */
66 };
67
68 /*-----------------------------------------------------------------------
69 * Functions
70 */
71 static ulong flash_get_size(vu_long * addr, flash_info_t * info);
72 static int write_word(flash_info_t * info, ulong dest, ulong data);
73
74
75 #ifdef CONFIG_OCOTEA
76 #define ADDR0 0x5555
77 #define ADDR1 0x2aaa
78 #define FLASH_WORD_SIZE unsigned char
79 #endif
80
81 /*-----------------------------------------------------------------------
82 */
83
84 unsigned long flash_init(void)
85 {
86 unsigned long total_b = 0;
87 unsigned long size_b[CFG_MAX_FLASH_BANKS];
88 unsigned char *fpga_base = (unsigned char *) CFG_FPGA_BASE;
89 unsigned char switch_status;
90 unsigned short index = 0;
91 int i;
92
93 /* read FPGA base register FPGA_REG0 */
94 switch_status = *fpga_base;
95
96 /* check the bitmap of switch status */
97 if (switch_status & BOOT_SMALL_FLASH) {
98 index += BOOT_SMALL_FLASH_VAL;
99 }
100 if (switch_status & FLASH_ONBD_N) {
101 index += FLASH_ONBD_N_VAL;
102 }
103 if (switch_status & FLASH_SRAM_SEL) {
104 index += FLASH_SRAM_SEL_VAL;
105 }
106
107 DEBUGF("\n");
108 DEBUGF("FLASH: Index: %d\n", index);
109
110 /* Init: no FLASHes known */
111 for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
112 flash_info[i].flash_id = FLASH_UNKNOWN;
113 flash_info[i].sector_count = -1;
114 flash_info[i].size = 0;
115
116 /* check whether the address is 0 */
117 if (flash_addr_table[index][i] == 0) {
118 continue;
119 }
120
121 /* call flash_get_size() to initialize sector address */
122 size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i], &flash_info[i]);
123 flash_info[i].size = size_b[i];
124 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
125 printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
126 i, size_b[i], size_b[i] << 20);
127 flash_info[i].sector_count = -1;
128 flash_info[i].size = 0;
129 }
130
131 total_b += flash_info[i].size;
132 }
133
134 return total_b;
135 }
136
137 /*-----------------------------------------------------------------------
138 */
139 void flash_print_info(flash_info_t * info)
140 {
141 int i;
142 int k;
143 int size;
144 int erased;
145 volatile unsigned long *flash;
146
147 if (info->flash_id == FLASH_UNKNOWN) {
148 printf("missing or unknown FLASH type\n");
149 return;
150 }
151
152 switch (info->flash_id & FLASH_VENDMASK) {
153 case FLASH_MAN_AMD:
154 printf("AMD ");
155 break;
156 case FLASH_MAN_FUJ:
157 printf("FUJITSU ");
158 break;
159 case FLASH_MAN_SST:
160 printf("SST ");
161 break;
162 default:
163 printf("Unknown Vendor ");
164 break;
165 }
166
167 switch (info->flash_id & FLASH_TYPEMASK) {
168 case FLASH_AM040:
169 printf("AM29F040 (512 Kbit, uniform sector size)\n");
170 break;
171 case FLASH_AM400B:
172 printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
173 break;
174 case FLASH_AM400T:
175 printf("AM29LV400T (4 Mbit, top boot sector)\n");
176 break;
177 case FLASH_AM800B:
178 printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
179 break;
180 case FLASH_AM800T:
181 printf("AM29LV800T (8 Mbit, top boot sector)\n");
182 break;
183 case FLASH_AM160B:
184 printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
185 break;
186 case FLASH_AM160T:
187 printf("AM29LV160T (16 Mbit, top boot sector)\n");
188 break;
189 case FLASH_AM320B:
190 printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
191 break;
192 case FLASH_AM320T:
193 printf("AM29LV320T (32 Mbit, top boot sector)\n");
194 break;
195 case FLASH_AMDLV033C:
196 printf("AM29LV033C (32 Mbit, top boot sector)\n");
197 break;
198 case FLASH_SST800A:
199 printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
200 break;
201 case FLASH_SST160A:
202 printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
203 break;
204 default:
205 printf("Unknown Chip Type\n");
206 break;
207 }
208
209 printf(" Size: %ld KB in %d Sectors\n",
210 info->size >> 10, info->sector_count);
211
212 printf(" Sector Start Addresses:");
213 for (i = 0; i < info->sector_count; ++i) {
214 /*
215 * Check if whole sector is erased
216 */
217 if (i != (info->sector_count - 1))
218 size = info->start[i + 1] - info->start[i];
219 else
220 size = info->start[0] + info->size - info->start[i];
221 erased = 1;
222 flash = (volatile unsigned long *) info->start[i];
223 size = size >> 2; /* divide by 4 for longword access */
224 for (k = 0; k < size; k++) {
225 if (*flash++ != 0xffffffff) {
226 erased = 0;
227 break;
228 }
229 }
230
231 if ((i % 5) == 0)
232 printf("\n ");
233 printf(" %08lX%s%s",
234 info->start[i],
235 erased ? " E" : " ", info->protect[i] ? "RO " : " ");
236 }
237 printf("\n");
238 return;
239 }
240
241 /*-----------------------------------------------------------------------
242 */
243
244 /*
245 * The following code cannot be run from FLASH!
246 */
247 static ulong flash_get_size(vu_long * addr, flash_info_t * info)
248 {
249 short i;
250 FLASH_WORD_SIZE value;
251 ulong base = (ulong) addr;
252 volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) addr;
253
254 DEBUGF("FLASH ADDR: %08x\n", (unsigned) addr);
255
256 /* Write auto select command: read Manufacturer ID */
257 udelay(10000);
258 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
259 udelay(1000);
260 addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
261 udelay(1000);
262 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00900090;
263 udelay(1000);
264
265 value = addr2[0];
266 DEBUGF("FLASH MANUFACT: %x\n", value);
267
268 switch (value) {
269 case (FLASH_WORD_SIZE) AMD_MANUFACT:
270 info->flash_id = FLASH_MAN_AMD;
271 break;
272 case (FLASH_WORD_SIZE) FUJ_MANUFACT:
273 info->flash_id = FLASH_MAN_FUJ;
274 break;
275 case (FLASH_WORD_SIZE) SST_MANUFACT:
276 info->flash_id = FLASH_MAN_SST;
277 break;
278 case (FLASH_WORD_SIZE) STM_MANUFACT:
279 info->flash_id = FLASH_MAN_STM;
280 break;
281 default:
282 info->flash_id = FLASH_UNKNOWN;
283 info->sector_count = 0;
284 info->size = 0;
285 return (0); /* no or unknown flash */
286 }
287
288 value = addr2[1]; /* device ID */
289
290 DEBUGF("\nFLASH DEVICEID: %x\n", value);
291
292 switch (value) {
293 case (FLASH_WORD_SIZE) AMD_ID_LV040B:
294 info->flash_id += FLASH_AM040;
295 info->sector_count = 8;
296 info->size = 0x0080000; /* => 512 ko */
297 break;
298 case (FLASH_WORD_SIZE) AMD_ID_F040B:
299 info->flash_id += FLASH_AM040;
300 info->sector_count = 8;
301 info->size = 0x0080000; /* => 512 ko */
302 break;
303 case (FLASH_WORD_SIZE) AMD_ID_LV033C:
304 info->flash_id += FLASH_AMDLV033C;
305 info->sector_count = 64;
306 info->size = 0x00400000;
307 break; /* => 4 MB */
308 default:
309 info->flash_id = FLASH_UNKNOWN;
310 return (0); /* => no or unknown flash */
311 }
312
313 /* set up sector start address table */
314 if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
315 (info->flash_id == FLASH_AM040) ||
316 (info->flash_id == FLASH_AMD016)) {
317 for (i = 0; i < info->sector_count; i++)
318 info->start[i] = base + (i * 0x00010000);
319 } else {
320 if (info->flash_id & FLASH_BTYPE) {
321 /* set sector offsets for bottom boot block type */
322 info->start[0] = base + 0x00000000;
323 info->start[1] = base + 0x00004000;
324 info->start[2] = base + 0x00006000;
325 info->start[3] = base + 0x00008000;
326 for (i = 4; i < info->sector_count; i++) {
327 info->start[i] = base + (i * 0x00010000) - 0x00030000;
328 }
329 } else {
330 /* set sector offsets for top boot block type */
331 i = info->sector_count - 1;
332 info->start[i--] = base + info->size - 0x00004000;
333 info->start[i--] = base + info->size - 0x00006000;
334 info->start[i--] = base + info->size - 0x00008000;
335 for (; i >= 0; i--) {
336 info->start[i] = base + i * 0x00010000;
337 }
338 }
339 }
340
341 /* check for protected sectors */
342 for (i = 0; i < info->sector_count; i++) {
343 /* read sector protection at sector address, (A7 .. A0) = 0x02 */
344 /* D0 = 1 if protected */
345 addr2 = (volatile FLASH_WORD_SIZE *) (info->start[i]);
346 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
347 info->protect[i] = 0;
348 else
349 info->protect[i] = addr2[2] & 1;
350 }
351
352 /* issue bank reset to return to read mode */
353 addr2[0] = (FLASH_WORD_SIZE) 0x00F000F0;
354
355 /*
356 * Prevent writes to uninitialized FLASH.
357 */
358 if (info->flash_id != FLASH_UNKNOWN) {
359 /* ? ? ? */
360 }
361
362 return (info->size);
363 }
364
365 int wait_for_DQ7(flash_info_t * info, int sect)
366 {
367 ulong start, now, last;
368 volatile FLASH_WORD_SIZE *addr =
369 (FLASH_WORD_SIZE *) (info->start[sect]);
370
371 start = get_timer(0);
372 last = start;
373 while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
374 (FLASH_WORD_SIZE) 0x00800080) {
375 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
376 printf("Timeout\n");
377 return -1;
378 }
379 /* show that we're waiting */
380 if ((now - last) > 1000) { /* every second */
381 putc('.');
382 last = now;
383 }
384 }
385 return 0;
386 }
387
388 /*-----------------------------------------------------------------------
389 */
390
391 int flash_erase(flash_info_t * info, int s_first, int s_last)
392 {
393 volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
394 volatile FLASH_WORD_SIZE *addr2;
395 int flag, prot, sect, l_sect;
396 int i;
397
398 if ((s_first < 0) || (s_first > s_last)) {
399 if (info->flash_id == FLASH_UNKNOWN) {
400 printf("- missing\n");
401 } else {
402 printf("- no sectors to erase\n");
403 }
404 return 1;
405 }
406
407 if (info->flash_id == FLASH_UNKNOWN) {
408 printf("Can't erase unknown flash type - aborted\n");
409 return 1;
410 }
411
412 prot = 0;
413 for (sect = s_first; sect <= s_last; ++sect) {
414 if (info->protect[sect]) {
415 prot++;
416 }
417 }
418
419 if (prot) {
420 printf("- Warning: %d protected sectors will not be erased!\n",
421 prot);
422 } else {
423 printf("\n");
424 }
425
426 l_sect = -1;
427
428 /* Disable interrupts which might cause a timeout here */
429 flag = disable_interrupts();
430
431 /* Start erase on unprotected sectors */
432 for (sect = s_first; sect <= s_last; sect++) {
433 if (info->protect[sect] == 0) { /* not protected */
434 addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
435 printf("Erasing sector %p\n", addr2);
436
437 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
438 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
439 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
440 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
441 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
442 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
443 addr2[0] = (FLASH_WORD_SIZE) 0x00500050; /* block erase */
444 for (i = 0; i < 50; i++)
445 udelay(1000); /* wait 1 ms */
446 } else {
447 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
448 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
449 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
450 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
451 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
452 addr2[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */
453 }
454 l_sect = sect;
455 /*
456 * Wait for each sector to complete, it's more
457 * reliable. According to AMD Spec, you must
458 * issue all erase commands within a specified
459 * timeout. This has been seen to fail, especially
460 * if printf()s are included (for debug)!!
461 */
462 wait_for_DQ7(info, sect);
463 }
464 }
465
466 /* re-enable interrupts if necessary */
467 if (flag)
468 enable_interrupts();
469
470 /* wait at least 80us - let's wait 1 ms */
471 udelay(1000);
472
473 /* reset to read mode */
474 addr = (FLASH_WORD_SIZE *) info->start[0];
475 addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
476
477 printf(" done\n");
478 return 0;
479 }
480
481 /*-----------------------------------------------------------------------
482 * Copy memory to flash, returns:
483 * 0 - OK
484 * 1 - write timeout
485 * 2 - Flash not erased
486 */
487 int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
488 {
489 ulong cp, wp, data;
490 int i, l, rc;
491
492 wp = (addr & ~3); /* get lower word aligned address */
493
494 /*
495 * handle unaligned start bytes
496 */
497 if ((l = addr - wp) != 0) {
498 data = 0;
499 for (i = 0, cp = wp; i < l; ++i, ++cp) {
500 data = (data << 8) | (*(uchar *) cp);
501 }
502 for (; i < 4 && cnt > 0; ++i) {
503 data = (data << 8) | *src++;
504 --cnt;
505 ++cp;
506 }
507 for (; cnt == 0 && i < 4; ++i, ++cp) {
508 data = (data << 8) | (*(uchar *) cp);
509 }
510
511 if ((rc = write_word(info, wp, data)) != 0) {
512 return (rc);
513 }
514 wp += 4;
515 }
516
517 /*
518 * handle word aligned part
519 */
520 while (cnt >= 4) {
521 data = 0;
522 for (i = 0; i < 4; ++i) {
523 data = (data << 8) | *src++;
524 }
525 if ((rc = write_word(info, wp, data)) != 0) {
526 return (rc);
527 }
528 wp += 4;
529 cnt -= 4;
530 }
531
532 if (cnt == 0) {
533 return (0);
534 }
535
536 /*
537 * handle unaligned tail bytes
538 */
539 data = 0;
540 for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
541 data = (data << 8) | *src++;
542 --cnt;
543 }
544 for (; i < 4; ++i, ++cp) {
545 data = (data << 8) | (*(uchar *) cp);
546 }
547
548 return (write_word(info, wp, data));
549 }
550
551 /*-----------------------------------------------------------------------
552 * Write a word to Flash, returns:
553 * 0 - OK
554 * 1 - write timeout
555 * 2 - Flash not erased
556 */
557 static int write_word(flash_info_t * info, ulong dest, ulong data)
558 {
559 volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) (info->start[0]);
560 volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
561 volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
562 ulong start;
563 int i;
564
565 /* Check if Flash is (sufficiently) erased */
566 if ((*((volatile FLASH_WORD_SIZE *) dest) &
567 (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
568 return (2);
569 }
570
571 for (i = 0; i < 4 / sizeof(FLASH_WORD_SIZE); i++) {
572 int flag;
573
574 /* Disable interrupts which might cause a timeout here */
575 flag = disable_interrupts();
576
577 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
578 addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
579 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
580
581 dest2[i] = data2[i];
582
583 /* re-enable interrupts if necessary */
584 if (flag)
585 enable_interrupts();
586
587 /* data polling for D7 */
588 start = get_timer(0);
589 while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
590 (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
591
592 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
593 return (1);
594 }
595 }
596 }
597
598 return (0);
599 }