blob: e2739731e03ca9e632bf39e98304120df9628091 [file] [log] [blame]
wdenk78924a72004-04-18 21:45:42 +00001/*
2 * (C) Copyright 2003, Dan Malek, Embedded Edge, LLC. <dan@embeddededge.com>
3 * Copied from ADS85xx.
4 * Updated to support the Silicon Tx GP3 8560. We should only find
5 * two Intel 28F640 parts in 16-bit mode (i.e. 32-bit wide flash),
6 * but I left other code here in case people order custom boards.
7 *
8 * (C) Copyright 2003 Motorola Inc.
9 * Xianghua Xiao,(X.Xiao@motorola.com)
10 *
11 * (C) Copyright 2000, 2001
12 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
13 *
14 * (C) Copyright 2001, Stuart Hughes, Lineo Inc, stuarth@lineo.com
15 * Add support the Sharp chips on the mpc8260ads.
16 * I started with board/ip860/flash.c and made changes I found in
17 * the MTD project by David Schleef.
18 *
19 * See file CREDITS for list of people who contributed to this
20 * project.
21 *
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License as
24 * published by the Free Software Foundation; either version 2 of
25 * the License, or (at your option) any later version.
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
35 * MA 02111-1307 USA
36 */
37
38#include <common.h>
39
40#if !defined(CFG_NO_FLASH)
41
42flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
43
44#if defined(CFG_ENV_IS_IN_FLASH)
45# ifndef CFG_ENV_ADDR
46# define CFG_ENV_ADDR (CFG_FLASH_BASE + CFG_ENV_OFFSET)
47# endif
48# ifndef CFG_ENV_SIZE
49# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
50# endif
51# ifndef CFG_ENV_SECT_SIZE
52# define CFG_ENV_SECT_SIZE CFG_ENV_SIZE
53# endif
54#endif
55
56#undef DEBUG
57
58/*-----------------------------------------------------------------------
59 * Functions
60 */
61static ulong flash_get_size (vu_long *addr, flash_info_t *info);
62static int write_word (flash_info_t *info, ulong dest, ulong data);
63static int clear_block_lock_bit(vu_long * addr);
64/*-----------------------------------------------------------------------
65 */
66
67unsigned long flash_init (void)
68{
69 unsigned long size;
70 int i;
71
72 /* Init: enable write,
73 * or we cannot even write flash commands
74 */
75 for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
76 flash_info[i].flash_id = FLASH_UNKNOWN;
77
78 /* set the default sector offset */
79 }
80
81 /* Static FLASH Bank configuration here - FIXME XXX */
82
83 size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
84
85 if (flash_info[0].flash_id == FLASH_UNKNOWN) {
86 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
87 size, size<<20);
88 }
89
90 /* Re-do sizing to get full correct info */
91 size = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
92
93 flash_info[0].size = size;
94
95#if !defined(CONFIG_RAM_AS_FLASH)
96#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
97 /* monitor protection ON by default */
98 flash_protect(FLAG_PROTECT_SET,
99 CFG_MONITOR_BASE,
100 CFG_MONITOR_BASE+monitor_flash_len-1,
101 &flash_info[0]);
102#endif
103
104#ifdef CFG_ENV_IS_IN_FLASH
105 /* ENV protection ON by default */
106 flash_protect(FLAG_PROTECT_SET,
107 CFG_ENV_ADDR,
108 CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
109 &flash_info[0]);
110#endif
111#endif
112 return (size);
113}
114
115/*-----------------------------------------------------------------------
116 */
117void flash_print_info (flash_info_t *info)
118{
119 int i;
120
121 if (info->flash_id == FLASH_UNKNOWN) {
122 printf ("missing or unknown FLASH type\n");
123 return;
124 }
125
126 switch (info->flash_id & FLASH_VENDMASK) {
127 case FLASH_MAN_INTEL: printf ("Intel "); break;
128 case FLASH_MAN_SHARP: printf ("Sharp "); break;
129 default: printf ("Unknown Vendor "); break;
130 }
131
132 switch (info->flash_id & FLASH_TYPEMASK) {
133 case FLASH_28F640C3T: printf ("28F640C3T (64 Mbit x 2, 128 x 128k)\n");
134 break;
135 default: printf ("Unknown Chip Type\n");
136 break;
137 }
138
139 printf (" Size: %ld MB in %d Sectors\n",
140 info->size >> 20, info->sector_count);
141
142 printf (" Sector Start Addresses:");
143 for (i=0; i<info->sector_count; ++i) {
144 if ((i % 5) == 0)
145 printf ("\n ");
146 printf (" %08lX%s",
147 info->start[i],
148 info->protect[i] ? " (RO)" : " "
149 );
150 }
151 printf ("\n");
152}
153
154/*
155 * The following code cannot be run from FLASH!
156 */
157
158static ulong flash_get_size (vu_long *addr, flash_info_t *info)
159{
160 short i;
161 ulong value;
162 ulong base = (ulong)addr;
163 ulong sector_offset;
164
165#ifdef DEBUG
166 printf("Check flash at 0x%08x\n",(uint)addr);
167#endif
168 /* Write "Intelligent Identifier" command: read Manufacturer ID */
169 *addr = 0x90909090;
170 udelay(20);
171 asm("sync");
172
173 value = addr[0] & 0x00FF00FF;
174
175#ifdef DEBUG
176 printf("manufacturer=0x%x\n",(uint)value);
177#endif
178 switch (value) {
179 case MT_MANUFACT: /* SHARP, MT or => Intel */
180 case INTEL_ALT_MANU:
181 info->flash_id = FLASH_MAN_INTEL;
182 break;
183 default:
184 printf("unknown manufacturer: %x\n", (unsigned int)value);
185 info->flash_id = FLASH_UNKNOWN;
186 info->sector_count = 0;
187 info->size = 0;
188 return (0); /* no or unknown flash */
189 }
190
191 value = addr[1]; /* device ID */
192
193#ifdef DEBUG
194 printf("deviceID=0x%x\n",(uint)value);
195#endif
196 switch (value) {
197
198 case (INTEL_ID_28F640C3T):
199 info->flash_id += FLASH_28F640C3T;
200 info->sector_count = 135;
201 info->size = 0x01000000;
202 sector_offset = 0x20000;
203 break; /* => 2x8 MB */
204
205 default:
206 info->flash_id = FLASH_UNKNOWN;
207 return (0); /* => no or unknown flash */
208
209 }
210
211 /* set up sector start address table
212 * The first 127 blocks are large, the last 8 are small.
213 */
214 for (i = 0; i < 127; i++) {
215 info->start[i] = base;
216 base += sector_offset;
217 /* Sectors are locked upon reset */
218 info->protect[i] = 0;
219 }
220 for (i = 127; i < 135; i++) {
221 info->start[i] = base;
222 base += 0x4000;
223 /* Sectors are locked upon reset */
224 info->protect[i] = 0;
225 }
226
227
228 /*
229 * Prevent writes to uninitialized FLASH.
230 */
231 if (info->flash_id != FLASH_UNKNOWN) {
232 addr = (vu_long *)info->start[0];
233 *addr = 0xFFFFFF; /* reset bank to read array mode */
234 asm("sync");
235 }
236
237 return (info->size);
238}
239
240
241/*-----------------------------------------------------------------------
242 */
243
244int flash_erase (flash_info_t *info, int s_first, int s_last)
245{
246 int flag, prot, sect;
247 ulong start, now, last;
248
249 if ((s_first < 0) || (s_first > s_last)) {
250 if (info->flash_id == FLASH_UNKNOWN) {
251 printf ("- missing\n");
252 } else {
253 printf ("- no sectors to erase\n");
254 }
255 return 1;
256 }
257
258 if ( ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL)
259 && ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_SHARP) ) {
260 printf ("Can't erase unknown flash type %08lx - aborted\n",
261 info->flash_id);
262 return 1;
263 }
264
265 prot = 0;
266 for (sect=s_first; sect<=s_last; ++sect) {
267 if (info->protect[sect]) {
268 prot++;
269 }
270 }
271
272 if (prot) {
273 printf ("- Warning: %d protected sectors will not be erased!\n",
274 prot);
275 } else {
276 printf ("\n");
277 }
278
279#ifdef DEBUG
280 printf("\nFlash Erase:\n");
281#endif
282 /* Make Sure Block Lock Bit is not set. */
283 if(clear_block_lock_bit((vu_long *)(info->start[s_first]))){
284 return 1;
285 }
286
287 /* Start erase on unprotected sectors */
288#if defined(DEBUG)
289 printf("Begin to erase now,s_first=0x%x s_last=0x%x...\n",s_first,s_last);
290#endif
291 for (sect = s_first; sect<=s_last; sect++) {
292 if (info->protect[sect] == 0) { /* not protected */
293 vu_long *addr = (vu_long *)(info->start[sect]);
294 asm("sync");
295
296 last = start = get_timer (0);
297
298 /* Disable interrupts which might cause a timeout here */
299 flag = disable_interrupts();
300
301 /* Reset Array */
302 *addr = 0xffffffff;
303 asm("sync");
304 /* Clear Status Register */
305 *addr = 0x50505050;
306 asm("sync");
307 /* Single Block Erase Command */
308 *addr = 0x20202020;
309 asm("sync");
310 /* Confirm */
311 *addr = 0xD0D0D0D0;
312 asm("sync");
313
314 if((info->flash_id & FLASH_TYPEMASK) != FLASH_LH28F016SCT) {
315 /* Resume Command, as per errata update */
316 *addr = 0xD0D0D0D0;
317 asm("sync");
318 }
319
320 /* re-enable interrupts if necessary */
321 if (flag)
322 enable_interrupts();
323
324 /* wait at least 80us - let's wait 1 ms */
325 udelay (1000);
326 while ((*addr & 0x00800080) != 0x00800080) {
327 if(*addr & 0x00200020){
328 printf("Error in Block Erase - Lock Bit may be set!\n");
329 printf("Status Register = 0x%X\n", (uint)*addr);
330 *addr = 0xFFFFFFFF; /* reset bank */
331 asm("sync");
332 return 1;
333 }
334 if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
335 printf ("Timeout\n");
336 *addr = 0xFFFFFFFF; /* reset bank */
337 asm("sync");
338 return 1;
339 }
340 /* show that we're waiting */
341 if ((now - last) > 1000) { /* every second */
342 putc ('.');
343 last = now;
344 }
345 }
346
347 /* reset to read mode */
348 *addr = 0xFFFFFFFF;
349 asm("sync");
350 }
351 }
352
353 printf ("flash erase done\n");
354 return 0;
355}
356
357/*-----------------------------------------------------------------------
358 * Copy memory to flash, returns:
359 * 0 - OK
360 * 1 - write timeout
361 * 2 - Flash not erased
362 */
363
364int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
365{
366 ulong cp, wp, data;
367 int i, l, rc;
368
369 wp = (addr & ~3); /* get lower word aligned address */
370
371 /*
372 * handle unaligned start bytes
373 */
374 if ((l = addr - wp) != 0) {
375 data = 0;
376 for (i=0, cp=wp; i<l; ++i, ++cp) {
377 data = (data << 8) | (*(uchar *)cp);
378 }
379 for (; i<4 && cnt>0; ++i) {
380 data = (data << 8) | *src++;
381 --cnt;
382 ++cp;
383 }
384 for (; cnt==0 && i<4; ++i, ++cp) {
385 data = (data << 8) | (*(uchar *)cp);
386 }
387
388 if ((rc = write_word(info, wp, data)) != 0) {
389 return (rc);
390 }
391 wp += 4;
392 }
393
394 /*
395 * handle word aligned part
396 */
397 while (cnt >= 4) {
398 data = 0;
399 for (i=0; i<4; ++i) {
400 data = (data << 8) | *src++;
401 }
402 if ((rc = write_word(info, wp, data)) != 0) {
403 return (rc);
404 }
405 wp += 4;
406 cnt -= 4;
407 }
408
409 if (cnt == 0) {
410 return (0);
411 }
412
413 /*
414 * handle unaligned tail bytes
415 */
416 data = 0;
417 for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
418 data = (data << 8) | *src++;
419 --cnt;
420 }
421 for (; i<4; ++i, ++cp) {
422 data = (data << 8) | (*(uchar *)cp);
423 }
424
425 return (write_word(info, wp, data));
426}
427
428/*-----------------------------------------------------------------------
429 * Write a word to Flash, returns:
430 * 0 - OK
431 * 1 - write timeout
432 * 2 - Flash not erased
433 */
434static int write_word (flash_info_t *info, ulong dest, ulong data)
435{
436 vu_long *addr = (vu_long *)dest;
437 ulong start, csr;
438 int flag;
439
440 /* Check if Flash is (sufficiently) erased */
441 if ((*addr & data) != data) {
442 return (2);
443 }
444 /* Disable interrupts which might cause a timeout here */
445 flag = disable_interrupts();
446
447 /* Write Command */
448 *addr = 0x10101010;
449 asm("sync");
450
451 /* Write Data */
452 *addr = data;
453
454 /* re-enable interrupts if necessary */
455 if (flag)
456 enable_interrupts();
457
458 /* data polling for D7 */
459 start = get_timer (0);
460 flag = 0;
461
462 while (((csr = *addr) & 0x00800080) != 0x00800080) {
463 if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
464 flag = 1;
465 break;
466 }
467 }
468 if (csr & 0x40404040) {
469 printf ("CSR indicates write error (%08lx) at %08lx\n", csr, (ulong)addr);
470 flag = 1;
471 }
472
473 /* Clear Status Registers Command */
474 *addr = 0x50505050;
475 asm("sync");
476 /* Reset to read array mode */
477 *addr = 0xFFFFFFFF;
478 asm("sync");
479
480 return (flag);
481}
482
483/*-----------------------------------------------------------------------
484 * Clear Block Lock Bit, returns:
485 * 0 - OK
486 * 1 - Timeout
487 */
488
489static int clear_block_lock_bit(vu_long * addr)
490{
491 ulong start, now;
492
493 /* Reset Array */
494 *addr = 0xffffffff;
495 asm("sync");
496 /* Clear Status Register */
497 *addr = 0x50505050;
498 asm("sync");
499
500 *addr = 0x60606060;
501 asm("sync");
502 *addr = 0xd0d0d0d0;
503 asm("sync");
504
505 start = get_timer (0);
506 while((*addr & 0x00800080) != 0x00800080){
507 if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
508 printf ("Timeout on clearing Block Lock Bit\n");
509 *addr = 0xFFFFFFFF; /* reset bank */
510 asm("sync");
511 return 1;
512 }
513 }
514 return 0;
515}
516
517#endif /* !CFG_NO_FLASH */