blob: 15e688f7a2bb6c31a0153b6ab6e40267f11757b7 [file] [log] [blame]
wdenk00fe1612004-03-14 00:07:33 +00001/*
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
55flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
56
57static 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 */
71static ulong flash_get_size(vu_long * addr, flash_info_t * info);
72static 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
84unsigned 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 */
139void 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 */
247static 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 /*
353 * Prevent writes to uninitialized FLASH.
354 */
355 if (info->flash_id != FLASH_UNKNOWN) {
356 }
357
358 return (info->size);
359}
360
361int wait_for_DQ7(flash_info_t * info, int sect)
362{
363 ulong start, now, last;
364 volatile FLASH_WORD_SIZE *addr =
365 (FLASH_WORD_SIZE *) (info->start[sect]);
366
367 start = get_timer(0);
368 last = start;
369 while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
370 (FLASH_WORD_SIZE) 0x00800080) {
371 if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
372 printf("Timeout\n");
373 return -1;
374 }
375 /* show that we're waiting */
376 if ((now - last) > 1000) { /* every second */
377 putc('.');
378 last = now;
379 }
380 }
381 return 0;
382}
383
384/*-----------------------------------------------------------------------
385 */
386
387int flash_erase(flash_info_t * info, int s_first, int s_last)
388{
389 volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
390 volatile FLASH_WORD_SIZE *addr2;
391 int flag, prot, sect, l_sect;
392 int i;
393
394 if ((s_first < 0) || (s_first > s_last)) {
395 if (info->flash_id == FLASH_UNKNOWN) {
396 printf("- missing\n");
397 } else {
398 printf("- no sectors to erase\n");
399 }
400 return 1;
401 }
402
403 if (info->flash_id == FLASH_UNKNOWN) {
404 printf("Can't erase unknown flash type - aborted\n");
405 return 1;
406 }
407
408 prot = 0;
409 for (sect = s_first; sect <= s_last; ++sect) {
410 if (info->protect[sect]) {
411 prot++;
412 }
413 }
414
415 if (prot) {
416 printf("- Warning: %d protected sectors will not be erased!\n",
417 prot);
418 } else {
419 printf("\n");
420 }
421
422 l_sect = -1;
423
424 /* Disable interrupts which might cause a timeout here */
425 flag = disable_interrupts();
426
427 /* Start erase on unprotected sectors */
428 for (sect = s_first; sect <= s_last; sect++) {
429 if (info->protect[sect] == 0) { /* not protected */
430 addr2 = (FLASH_WORD_SIZE *) (info->start[sect]);
431 printf("Erasing sector %p\n", addr2);
432
433 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
434 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
435 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
436 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
437 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
438 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
439 addr2[0] = (FLASH_WORD_SIZE) 0x00500050; /* block erase */
440 for (i = 0; i < 50; i++)
441 udelay(1000); /* wait 1 ms */
442 } else {
443 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
444 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
445 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00800080;
446 addr[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
447 addr[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
448 addr2[0] = (FLASH_WORD_SIZE) 0x00300030; /* sector erase */
449 }
450 l_sect = sect;
451 /*
452 * Wait for each sector to complete, it's more
453 * reliable. According to AMD Spec, you must
454 * issue all erase commands within a specified
455 * timeout. This has been seen to fail, especially
456 * if printf()s are included (for debug)!!
457 */
458 wait_for_DQ7(info, sect);
459 }
460 }
461
462 /* re-enable interrupts if necessary */
463 if (flag)
464 enable_interrupts();
465
466 /* wait at least 80us - let's wait 1 ms */
467 udelay(1000);
468
469 /* reset to read mode */
470 addr = (FLASH_WORD_SIZE *) info->start[0];
471 addr[0] = (FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
472
473 printf(" done\n");
474 return 0;
475}
476
477/*-----------------------------------------------------------------------
478 * Copy memory to flash, returns:
479 * 0 - OK
480 * 1 - write timeout
481 * 2 - Flash not erased
482 */
483int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
484{
485 ulong cp, wp, data;
486 int i, l, rc;
487
488 wp = (addr & ~3); /* get lower word aligned address */
489
490 /*
491 * handle unaligned start bytes
492 */
493 if ((l = addr - wp) != 0) {
494 data = 0;
495 for (i = 0, cp = wp; i < l; ++i, ++cp) {
496 data = (data << 8) | (*(uchar *) cp);
497 }
498 for (; i < 4 && cnt > 0; ++i) {
499 data = (data << 8) | *src++;
500 --cnt;
501 ++cp;
502 }
503 for (; cnt == 0 && i < 4; ++i, ++cp) {
504 data = (data << 8) | (*(uchar *) cp);
505 }
506
507 if ((rc = write_word(info, wp, data)) != 0) {
508 return (rc);
509 }
510 wp += 4;
511 }
512
513 /*
514 * handle word aligned part
515 */
516 while (cnt >= 4) {
517 data = 0;
518 for (i = 0; i < 4; ++i) {
519 data = (data << 8) | *src++;
520 }
521 if ((rc = write_word(info, wp, data)) != 0) {
522 return (rc);
523 }
524 wp += 4;
525 cnt -= 4;
526 }
527
528 if (cnt == 0) {
529 return (0);
530 }
531
532 /*
533 * handle unaligned tail bytes
534 */
535 data = 0;
536 for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
537 data = (data << 8) | *src++;
538 --cnt;
539 }
540 for (; i < 4; ++i, ++cp) {
541 data = (data << 8) | (*(uchar *) cp);
542 }
543
544 return (write_word(info, wp, data));
545}
546
547/*-----------------------------------------------------------------------
548 * Write a word to Flash, returns:
549 * 0 - OK
550 * 1 - write timeout
551 * 2 - Flash not erased
552 */
553static int write_word(flash_info_t * info, ulong dest, ulong data)
554{
555 volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) (info->start[0]);
556 volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *) dest;
557 volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
558 ulong start;
559 int i;
560
561 /* Check if Flash is (sufficiently) erased */
562 if ((*((volatile FLASH_WORD_SIZE *) dest) &
563 (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
564 return (2);
565 }
566
567 for (i = 0; i < 4 / sizeof(FLASH_WORD_SIZE); i++) {
568 int flag;
569
570 /* Disable interrupts which might cause a timeout here */
571 flag = disable_interrupts();
572
573 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00AA00AA;
574 addr2[ADDR1] = (FLASH_WORD_SIZE) 0x00550055;
575 addr2[ADDR0] = (FLASH_WORD_SIZE) 0x00A000A0;
576
577 dest2[i] = data2[i];
578
579 /* re-enable interrupts if necessary */
580 if (flag)
581 enable_interrupts();
582
583 /* data polling for D7 */
584 start = get_timer(0);
585 while ((dest2[i] & (FLASH_WORD_SIZE) 0x00800080) !=
586 (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
587
588 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
589 return (1);
590 }
591 }
592 }
593
594 return (0);
595}