blob: 386822179d8a0f4fe3b5b1de8a8abbfb4ee592e7 [file] [log] [blame]
wdenkefa329c2004-03-23 20:18:25 +00001/*
2 * (C) Copyright 2001
3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4 *
5 * (C) Copyright 2001-2004
6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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#include <common.h>
28#include <linux/byteorder/swab.h>
29
30
31flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
32
33/* Board support for 1 or 2 flash devices */
34#define FLASH_PORT_WIDTH32
35#undef FLASH_PORT_WIDTH16
36
37#ifdef FLASH_PORT_WIDTH16
38#define FLASH_PORT_WIDTH ushort
39#define FLASH_PORT_WIDTHV vu_short
40#define SWAP(x) (x)
41#else
42#define FLASH_PORT_WIDTH ulong
43#define FLASH_PORT_WIDTHV vu_long
44#define SWAP(x) (x)
45#endif
46
47/* Intel-compatible flash ID */
48#define INTEL_COMPAT 0x00890089
49#define INTEL_ALT 0x00B000B0
50
51/* Intel-compatible flash commands */
52#define INTEL_PROGRAM 0x00100010
53#define INTEL_ERASE 0x00200020
54#define INTEL_CLEAR 0x00500050
55#define INTEL_LOCKBIT 0x00600060
56#define INTEL_PROTECT 0x00010001
57#define INTEL_STATUS 0x00700070
58#define INTEL_READID 0x00900090
59#define INTEL_CONFIRM 0x00D000D0
60#define INTEL_RESET 0xFFFFFFFF
61
62/* Intel-compatible flash status bits */
63#define INTEL_FINISHED 0x00800080
64#define INTEL_OK 0x00800080
65
66#define FPW FLASH_PORT_WIDTH
67#define FPWV FLASH_PORT_WIDTHV
68
69#define mb() __asm__ __volatile__ ("" : : : "memory")
70
71/*-----------------------------------------------------------------------
72 * Functions
73 */
74static ulong flash_get_size (FPW *addr, flash_info_t *info);
75static int write_data (flash_info_t *info, ulong dest, FPW data);
76static void flash_get_offsets (ulong base, flash_info_t *info);
77void inline spin_wheel (void);
Wolfgang Denk010162e2005-07-30 16:39:27 +020078static void flash_sync_real_protect (flash_info_t * info);
79static unsigned char intel_sector_protected (flash_info_t *info, ushort sector);
wdenkefa329c2004-03-23 20:18:25 +000080
81/*-----------------------------------------------------------------------
82 */
83
84unsigned long flash_init (void)
85{
86 int i;
87 ulong size = 0;
wdenk49822e22004-06-19 21:19:10 +000088 extern void flash_preinit(void);
89 extern void flash_afterinit(ulong, ulong);
90 ulong flashbase = CFG_FLASH_BASE;
91
92 flash_preinit();
wdenkefa329c2004-03-23 20:18:25 +000093
94 for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
95 switch (i) {
96 case 0:
wdenk49822e22004-06-19 21:19:10 +000097 memset(&flash_info[i], 0, sizeof(flash_info_t));
98 flash_get_size ((FPW *) flashbase, &flash_info[i]);
99 flash_get_offsets (flash_info[i].start[0], &flash_info[i]);
wdenkefa329c2004-03-23 20:18:25 +0000100 break;
101 default:
102 panic ("configured to many flash banks!\n");
103 break;
104 }
105 size += flash_info[i].size;
Wolfgang Denk010162e2005-07-30 16:39:27 +0200106
107 /* get the h/w and s/w protection status in sync */
108 flash_sync_real_protect(&flash_info[i]);
wdenkefa329c2004-03-23 20:18:25 +0000109 }
110
111 /* Protect monitor and environment sectors
112 */
wdenk49822e22004-06-19 21:19:10 +0000113#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
114#ifndef CONFIG_BOOT_ROM
wdenkefa329c2004-03-23 20:18:25 +0000115 flash_protect ( FLAG_PROTECT_SET,
116 CFG_MONITOR_BASE,
117 CFG_MONITOR_BASE + monitor_flash_len - 1,
118 &flash_info[0] );
wdenk49822e22004-06-19 21:19:10 +0000119#endif
120#endif
wdenkefa329c2004-03-23 20:18:25 +0000121
wdenk49822e22004-06-19 21:19:10 +0000122#ifdef CFG_ENV_IS_IN_FLASH
wdenkefa329c2004-03-23 20:18:25 +0000123 flash_protect ( FLAG_PROTECT_SET,
124 CFG_ENV_ADDR,
125 CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
wdenk49822e22004-06-19 21:19:10 +0000126#endif
127
128 flash_afterinit(flash_info[0].start[0], flash_info[0].size);
wdenkefa329c2004-03-23 20:18:25 +0000129
130 return size;
131}
132
133/*-----------------------------------------------------------------------
134 */
135static void flash_get_offsets (ulong base, flash_info_t *info)
136{
137 int i;
138
139 if (info->flash_id == FLASH_UNKNOWN) {
140 return;
141 }
142
143 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
144 for (i = 0; i < info->sector_count; i++) {
145 info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
wdenkefa329c2004-03-23 20:18:25 +0000146 }
147 }
148}
149
150/*-----------------------------------------------------------------------
151 */
152void flash_print_info (flash_info_t *info)
153{
154 int i;
155
156 if (info->flash_id == FLASH_UNKNOWN) {
157 printf ("missing or unknown FLASH type\n");
158 return;
159 }
160
161 switch (info->flash_id & FLASH_VENDMASK) {
162 case FLASH_MAN_INTEL:
163 printf ("INTEL ");
164 break;
165 default:
166 printf ("Unknown Vendor ");
167 break;
168 }
169
170 switch (info->flash_id & FLASH_TYPEMASK) {
171 case FLASH_28F128J3A:
172 printf ("28F128J3A\n");
173 break;
174
175 case FLASH_28F640J3A:
176 printf ("28F640J3A\n");
177 break;
178
179 case FLASH_28F320J3A:
180 printf ("28F320J3A\n");
181 break;
182
183 default:
184 printf ("Unknown Chip Type\n");
185 break;
186 }
187
188 printf (" Size: %ld MB in %d Sectors\n",
189 info->size >> 20, info->sector_count);
190
191 printf (" Sector Start Addresses:");
192 for (i = 0; i < info->sector_count; ++i) {
193 if ((i % 5) == 0)
194 printf ("\n ");
195 printf (" %08lX%s",
196 info->start[i],
197 info->protect[i] ? " (RO)" : " ");
198 }
199 printf ("\n");
200 return;
201}
202
203/*
204 * The following code cannot be run from FLASH!
205 */
206static ulong flash_get_size (FPW *addr, flash_info_t *info)
207{
208 volatile FPW value;
209
210 /* Write auto select command: read Manufacturer ID */
211 addr[0x5555] = (FPW) 0x00AA00AA;
212 addr[0x2AAA] = (FPW) 0x00550055;
213 addr[0x5555] = (FPW) 0x00900090;
214
215 mb ();
wdenk49822e22004-06-19 21:19:10 +0000216 udelay(100);
217
wdenkefa329c2004-03-23 20:18:25 +0000218 value = addr[0];
219
220 switch (value) {
221
222 case (FPW) INTEL_MANUFACT:
223 info->flash_id = FLASH_MAN_INTEL;
224 break;
225
226 default:
227 info->flash_id = FLASH_UNKNOWN;
228 info->sector_count = 0;
229 info->size = 0;
230 addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
231 return (0); /* no or unknown flash */
232 }
233
234 mb ();
235 value = addr[1]; /* device ID */
236
237 switch (value) {
238
239 case (FPW) INTEL_ID_28F128J3A:
240 info->flash_id += FLASH_28F128J3A;
241 info->sector_count = 128;
242 info->size = 0x02000000;
wdenk49822e22004-06-19 21:19:10 +0000243 info->start[0] = CFG_FLASH_BASE;
wdenkefa329c2004-03-23 20:18:25 +0000244 break; /* => 32 MB */
245
246 case (FPW) INTEL_ID_28F640J3A:
247 info->flash_id += FLASH_28F640J3A;
248 info->sector_count = 64;
249 info->size = 0x01000000;
wdenk49822e22004-06-19 21:19:10 +0000250 info->start[0] = CFG_FLASH_BASE + 0x01000000;
wdenkefa329c2004-03-23 20:18:25 +0000251 break; /* => 16 MB */
252
253 case (FPW) INTEL_ID_28F320J3A:
254 info->flash_id += FLASH_28F320J3A;
255 info->sector_count = 32;
wdenk49822e22004-06-19 21:19:10 +0000256 info->size = 0x800000;
257 info->start[0] = CFG_FLASH_BASE + 0x01800000;
wdenkefa329c2004-03-23 20:18:25 +0000258 break; /* => 8 MB */
259
260 default:
261 info->flash_id = FLASH_UNKNOWN;
262 break;
263 }
264
265 if (info->sector_count > CFG_MAX_FLASH_SECT) {
266 printf ("** ERROR: sector count %d > max (%d) **\n",
267 info->sector_count, CFG_MAX_FLASH_SECT);
268 info->sector_count = CFG_MAX_FLASH_SECT;
269 }
270
271 addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
272
273 return (info->size);
274}
275
276
Wolfgang Denk010162e2005-07-30 16:39:27 +0200277/*
278 * This function gets the u-boot flash sector protection status
279 * (flash_info_t.protect[]) in sync with the sector protection
280 * status stored in hardware.
281 */
282static void flash_sync_real_protect (flash_info_t * info)
283{
284 int i;
285
286 switch (info->flash_id & FLASH_TYPEMASK) {
287
288 case FLASH_28F128J3A:
289 case FLASH_28F640J3A:
290 case FLASH_28F320J3A:
291 for (i = 0; i < info->sector_count; ++i) {
292 info->protect[i] = intel_sector_protected(info, i);
293 }
294 break;
295 default:
296 /* no h/w protect support */
297 break;
298 }
299}
300
301
302/*
303 * checks if "sector" in bank "info" is protected. Should work on intel
304 * strata flash chips 28FxxxJ3x in 8-bit mode.
305 * Returns 1 if sector is protected (or timed-out while trying to read
306 * protection status), 0 if it is not.
307 */
308static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
309{
310 FPWV *addr;
311 FPWV *lock_conf_addr;
312 ulong start;
313 unsigned char ret;
314
315 /*
316 * first, wait for the WSM to be finished. The rationale for
317 * waiting for the WSM to become idle for at most
318 * CFG_FLASH_ERASE_TOUT is as follows. The WSM can be busy
319 * because of: (1) erase, (2) program or (3) lock bit
320 * configuration. So we just wait for the longest timeout of
321 * the (1)-(3), i.e. the erase timeout.
322 */
323
324 /* wait at least 35ns (W12) before issuing Read Status Register */
325 udelay(1);
326 addr = (FPWV *) info->start[sector];
327 *addr = (FPW) INTEL_STATUS;
328
329 start = get_timer (0);
330 while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
331 if (get_timer (start) > CFG_FLASH_ERASE_TOUT) {
332 *addr = (FPW) INTEL_RESET; /* restore read mode */
333 printf("WSM busy too long, can't get prot status\n");
334 return 1;
335 }
336 }
Wolfgang Denk095b8a32005-08-02 17:06:17 +0200337
Wolfgang Denk010162e2005-07-30 16:39:27 +0200338 /* issue the Read Identifier Codes command */
339 *addr = (FPW) INTEL_READID;
340
341 /* wait at least 35ns (W12) before reading */
342 udelay(1);
343
344 /* Intel example code uses offset of 2 for 16 bit flash */
345 lock_conf_addr = (FPWV *) info->start[sector] + 2;
346 ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;
347
348 /* put flash back in read mode */
349 *addr = (FPW) INTEL_RESET;
350
351 return ret;
352}
353
wdenkefa329c2004-03-23 20:18:25 +0000354/*-----------------------------------------------------------------------
355 */
356
357int flash_erase (flash_info_t *info, int s_first, int s_last)
358{
359 int flag, prot, sect;
360 ulong type, start, last;
361 int rcode = 0;
362
363 if ((s_first < 0) || (s_first > s_last)) {
364 if (info->flash_id == FLASH_UNKNOWN) {
365 printf ("- missing\n");
366 } else {
367 printf ("- no sectors to erase\n");
368 }
369 return 1;
370 }
371
372 type = (info->flash_id & FLASH_VENDMASK);
373 if ((type != FLASH_MAN_INTEL)) {
374 printf ("Can't erase unknown flash type %08lx - aborted\n",
375 info->flash_id);
376 return 1;
377 }
378
379 prot = 0;
380 for (sect = s_first; sect <= s_last; ++sect) {
381 if (info->protect[sect]) {
382 prot++;
383 }
384 }
385
386 if (prot) {
387 printf ("- Warning: %d protected sectors will not be erased!\n",
388 prot);
389 } else {
390 printf ("\n");
391 }
392
393 start = get_timer (0);
394 last = start;
395
396 /* Disable interrupts which might cause a timeout here */
397 flag = disable_interrupts ();
398
399 /* Start erase on unprotected sectors */
400 for (sect = s_first; sect <= s_last; sect++) {
401 if (info->protect[sect] == 0) { /* not protected */
402 FPWV *addr = (FPWV *) (info->start[sect]);
403 FPW status;
404
405 printf ("Erasing sector %2d ... ", sect);
406
407 /* arm simple, non interrupt dependent timer */
408 start = get_timer(0);
409
410 *addr = (FPW) 0x00500050; /* clear status register */
411 *addr = (FPW) 0x00200020; /* erase setup */
412 *addr = (FPW) 0x00D000D0; /* erase confirm */
413
414 while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
415 if (get_timer(start) > CFG_FLASH_ERASE_TOUT) {
416 printf ("Timeout\n");
417 *addr = (FPW) 0x00B000B0; /* suspend erase */
418 *addr = (FPW) 0x00FF00FF; /* reset to read mode */
419 rcode = 1;
420 break;
421 }
422 }
423
424 *addr = 0x00500050; /* clear status register cmd. */
425 *addr = 0x00FF00FF; /* resest to read mode */
426
427 printf (" done\n");
428 }
429 }
430 return rcode;
431}
432
433/*-----------------------------------------------------------------------
434 * Copy memory to flash, returns:
435 * 0 - OK
436 * 1 - write timeout
437 * 2 - Flash not erased
438 * 4 - Flash not identified
439 */
440
441int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
442{
443 ulong cp, wp;
444 FPW data;
445 int count, i, l, rc, port_width;
446
447 if (info->flash_id == FLASH_UNKNOWN) {
448 return 4;
449 }
450/* get lower word aligned address */
451#ifdef FLASH_PORT_WIDTH16
452 wp = (addr & ~1);
453 port_width = 2;
454#else
455 wp = (addr & ~3);
456 port_width = 4;
457#endif
458
459 /*
460 * handle unaligned start bytes
461 */
462 if ((l = addr - wp) != 0) {
463 data = 0;
464 for (i = 0, cp = wp; i < l; ++i, ++cp) {
465 data = (data << 8) | (*(uchar *) cp);
466 }
467 for (; i < port_width && cnt > 0; ++i) {
468 data = (data << 8) | *src++;
469 --cnt;
470 ++cp;
471 }
472 for (; cnt == 0 && i < port_width; ++i, ++cp) {
473 data = (data << 8) | (*(uchar *) cp);
474 }
475
476 if ((rc = write_data (info, wp, SWAP (data))) != 0) {
477 return (rc);
478 }
479 wp += port_width;
480 }
481
482 /*
483 * handle word aligned part
484 */
485 count = 0;
486 while (cnt >= port_width) {
487 data = 0;
488 for (i = 0; i < port_width; ++i) {
489 data = (data << 8) | *src++;
490 }
491 if ((rc = write_data (info, wp, SWAP (data))) != 0) {
492 return (rc);
493 }
494 wp += port_width;
495 cnt -= port_width;
496 if (count++ > 0x800) {
497 spin_wheel ();
498 count = 0;
499 }
500 }
501
502 if (cnt == 0) {
503 return (0);
504 }
505
506 /*
507 * handle unaligned tail bytes
508 */
509 data = 0;
510 for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
511 data = (data << 8) | *src++;
512 --cnt;
513 }
514 for (; i < port_width; ++i, ++cp) {
515 data = (data << 8) | (*(uchar *) cp);
516 }
517
518 return (write_data (info, wp, SWAP (data)));
519}
520
521/*-----------------------------------------------------------------------
522 * Write a word or halfword to Flash, returns:
523 * 0 - OK
524 * 1 - write timeout
525 * 2 - Flash not erased
526 */
527static int write_data (flash_info_t *info, ulong dest, FPW data)
528{
529 FPWV *addr = (FPWV *) dest;
530 ulong status;
531 ulong start;
532 int flag;
533
534 /* Check if Flash is (sufficiently) erased */
535 if ((*addr & data) != data) {
536 printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
537 return (2);
538 }
539 /* Disable interrupts which might cause a timeout here */
540 flag = disable_interrupts ();
541
542 *addr = (FPW) 0x00400040; /* write setup */
543 *addr = data;
544
545 /* arm simple, non interrupt dependent timer */
546 start = get_timer(0);
547
548 /* wait while polling the status register */
549 while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
550 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
551 *addr = (FPW) 0x00FF00FF; /* restore read mode */
552 return (1);
553 }
554 }
555
556 *addr = (FPW) 0x00FF00FF; /* restore read mode */
557
558 return (0);
559}
560
561void inline spin_wheel (void)
562{
563 static int p = 0;
564 static char w[] = "\\/-";
565
566 printf ("\010%c", w[p]);
567 (++p == 3) ? (p = 0) : 0;
568}
569
570/*-----------------------------------------------------------------------
571 * Set/Clear sector's lock bit, returns:
572 * 0 - OK
573 * 1 - Error (timeout, voltage problems, etc.)
574 */
Wolfgang Denk010162e2005-07-30 16:39:27 +0200575int flash_real_protect (flash_info_t *info, long sector, int prot)
wdenkefa329c2004-03-23 20:18:25 +0000576{
577 ulong start;
578 int i;
579 int rc = 0;
580 vu_long *addr = (vu_long *)(info->start[sector]);
581 int flag = disable_interrupts();
582
583 *addr = INTEL_CLEAR; /* Clear status register */
584 if (prot) { /* Set sector lock bit */
585 *addr = INTEL_LOCKBIT; /* Sector lock bit */
586 *addr = INTEL_PROTECT; /* set */
587 }
588 else { /* Clear sector lock bit */
589 *addr = INTEL_LOCKBIT; /* All sectors lock bits */
590 *addr = INTEL_CONFIRM; /* clear */
591 }
592
593 start = get_timer(0);
594
595 while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
596 if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) {
597 printf("Flash lock bit operation timed out\n");
598 rc = 1;
599 break;
600 }
601 }
602
603 if (*addr != INTEL_OK) {
604 printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
605 (uint)addr, (uint)*addr);
606 rc = 1;
607 }
608
609 if (!rc)
610 info->protect[sector] = prot;
611
612 /*
613 * Clear lock bit command clears all sectors lock bits, so
614 * we have to restore lock bits of protected sectors.
Wolfgang Denk010162e2005-07-30 16:39:27 +0200615 * WARNING: code below re-locks sectors only for one bank (info).
616 * This causes problems on boards where several banks share
617 * the same chip, as sectors in othere banks will be unlocked
618 * but not re-locked. It works fine on pm520 though, as there
619 * is only one chip and one bank.
wdenkefa329c2004-03-23 20:18:25 +0000620 */
621 if (!prot)
622 {
623 for (i = 0; i < info->sector_count; i++)
624 {
625 if (info->protect[i])
626 {
627 start = get_timer(0);
628 addr = (vu_long *)(info->start[i]);
629 *addr = INTEL_LOCKBIT; /* Sector lock bit */
630 *addr = INTEL_PROTECT; /* set */
631 while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
632 {
633 if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT)
634 {
635 printf("Flash lock bit operation timed out\n");
636 rc = 1;
637 break;
638 }
639 }
640 }
641 }
Wolfgang Denk010162e2005-07-30 16:39:27 +0200642 /*
643 * get the s/w sector protection status in sync with the h/w,
644 * in case something went wrong during the re-locking.
645 */
646 flash_sync_real_protect(info); /* resets flash to read mode */
wdenkefa329c2004-03-23 20:18:25 +0000647 }
648
649 if (flag)
650 enable_interrupts();
651
652 *addr = INTEL_RESET; /* Reset to read array mode */
653
654 return rc;
655}