1
2
3
4
5
6
7
8
9
10
11#include <common.h>
12#include <mpc8xx.h>
13#include "cpu87.h"
14
15flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
16
17
18
19ulong flash_int_get_size (volatile unsigned long *baseaddr,
20 flash_info_t * info)
21{
22 short i;
23 unsigned long flashtest_h, flashtest_l;
24
25 info->sector_count = info->size = 0;
26 info->flash_id = FLASH_UNKNOWN;
27
28
29
30 baseaddr[0] = 0x00900090;
31 baseaddr[1] = 0x00900090;
32
33 flashtest_h = baseaddr[0];
34 flashtest_l = baseaddr[1];
35
36 if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
37 return (0);
38
39 flashtest_h = baseaddr[2];
40 flashtest_l = baseaddr[3];
41
42 if (flashtest_h != flashtest_l)
43 return (0);
44
45 switch (flashtest_h) {
46 case INTEL_ID_28F160C3B:
47 info->flash_id = FLASH_28F160C3B;
48 info->sector_count = 39;
49 info->size = 0x00800000;
50 break;
51 case INTEL_ID_28F160F3B:
52 info->flash_id = FLASH_28F160F3B;
53 info->sector_count = 39;
54 info->size = 0x00800000;
55 break;
56 case INTEL_ID_28F640C3B:
57 info->flash_id = FLASH_28F640C3B;
58 info->sector_count = 135;
59 info->size = 0x02000000;
60 break;
61 default:
62 return (0);
63 }
64
65 info->flash_id |= INTEL_MANUFACT << 16;
66
67 if (info->flash_id & FLASH_BTYPE) {
68 volatile unsigned long *tmp = baseaddr;
69
70
71
72
73 for (i = 0; i < info->sector_count; i++) {
74 if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
75 ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
76 tmp[0] = 0x00600060;
77 tmp[1] = 0x00600060;
78 tmp[0] = 0x00D000D0;
79 tmp[1] = 0x00D000D0;
80 }
81 info->start[i] = (uint) tmp;
82 tmp += i < 8 ? 0x2000 : 0x10000;
83 }
84 }
85
86 memset (info->protect, 0, info->sector_count);
87
88 baseaddr[0] = 0x00FF00FF;
89 baseaddr[1] = 0x00FF00FF;
90
91 return (info->size);
92}
93
94static ulong flash_amd_get_size (vu_char *addr, flash_info_t *info)
95{
96 short i;
97 uchar vendor, devid;
98 ulong base = (ulong)addr;
99
100
101 addr[0x0555] = 0xAA;
102 addr[0x02AA] = 0x55;
103 addr[0x0555] = 0x90;
104
105 udelay(1000);
106
107 vendor = addr[0];
108 devid = addr[1] & 0xff;
109
110
111 if (vendor != 0x01) {
112 return 0;
113 }
114
115 vendor &= 0xf;
116 devid &= 0xff;
117
118 if (devid == AMD_ID_F040B) {
119 info->flash_id = vendor << 16 | devid;
120 info->sector_count = 8;
121 info->size = info->sector_count * 0x10000;
122 }
123 else if (devid == AMD_ID_F080B) {
124 info->flash_id = vendor << 16 | devid;
125 info->sector_count = 16;
126 info->size = 4 * info->sector_count * 0x10000;
127 }
128 else if (devid == AMD_ID_F016D) {
129 info->flash_id = vendor << 16 | devid;
130 info->sector_count = 32;
131 info->size = 4 * info->sector_count * 0x10000;
132 }
133 else {
134 printf ("## Unknown Flash Type: %02x\n", devid);
135 return 0;
136 }
137
138
139 for (i = 0; i < info->sector_count; i++) {
140
141 info->start[i] = base + i * (info->size / info->sector_count);
142
143
144 addr = (volatile unsigned char *)(info->start[i]);
145 info->protect[i] = addr[2] & 1;
146 }
147
148
149
150
151 if (info->flash_id != FLASH_UNKNOWN) {
152 addr = (vu_char *)info->start[0];
153 addr[0] = 0xF0;
154 }
155
156 return (info->size);
157}
158
159
160
161
162unsigned long flash_init (void)
163{
164 unsigned long size_b0 = 0;
165 unsigned long size_b1 = 0;
166 int i;
167
168
169
170 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
171 flash_info[i].flash_id = FLASH_UNKNOWN;
172 }
173
174
175 CPU86_BCR |= (CPU86_BCR_FWPT | CPU86_BCR_FWRE);
176
177
178
179 size_b0 = flash_int_get_size ((ulong *) CONFIG_SYS_FLASH_BASE, &flash_info[0]);
180 size_b1 = flash_amd_get_size ((uchar *) CONFIG_SYS_BOOTROM_BASE, &flash_info[1]);
181
182 if (size_b0 > 0 || size_b1 > 0) {
183
184 printf("(");
185
186 if (size_b0 > 0) {
187 puts ("Bank#1 - ");
188 print_size (size_b0, (size_b1 > 0) ? ", " : ") ");
189 }
190
191 if (size_b1 > 0) {
192 puts ("Bank#2 - ");
193 print_size (size_b1, ") ");
194 }
195 }
196 else {
197 printf ("## No FLASH found.\n");
198 return 0;
199 }
200
201
202
203#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_BOOTROM_BASE
204 if (size_b1) {
205
206
207
208
209 flash_protect (FLAG_PROTECT_SET,
210 CONFIG_SYS_MONITOR_BASE,
211 CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[1]
212 );
213 }
214#else
215#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
216 flash_protect (FLAG_PROTECT_SET,
217 CONFIG_SYS_MONITOR_BASE,
218 CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]
219 );
220#endif
221#endif
222
223#if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR)
224# ifndef CONFIG_ENV_SIZE
225# define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
226# endif
227# if CONFIG_ENV_ADDR >= CONFIG_SYS_BOOTROM_BASE
228 if (size_b1) {
229 flash_protect (FLAG_PROTECT_SET,
230 CONFIG_ENV_ADDR,
231 CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[1]);
232 }
233# else
234 flash_protect (FLAG_PROTECT_SET,
235 CONFIG_ENV_ADDR,
236 CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
237# endif
238#endif
239
240 return (size_b0 + size_b1);
241}
242
243
244
245void flash_print_info (flash_info_t * info)
246{
247 int i;
248
249 if (info->flash_id == FLASH_UNKNOWN) {
250 printf ("missing or unknown FLASH type\n");
251 return;
252 }
253
254 switch ((info->flash_id >> 16) & 0xff) {
255 case 0x89:
256 printf ("INTEL ");
257 break;
258 case 0x1:
259 printf ("AMD ");
260 break;
261 default:
262 printf ("Unknown Vendor ");
263 break;
264 }
265
266 switch (info->flash_id & FLASH_TYPEMASK) {
267 case FLASH_28F160C3B:
268 printf ("28F160C3B (16 Mbit, bottom sector)\n");
269 break;
270 case FLASH_28F160F3B:
271 printf ("28F160F3B (16 Mbit, bottom sector)\n");
272 break;
273 case FLASH_28F640C3B:
274 printf ("28F640C3B (64 M, bottom sector)\n");
275 break;
276 case AMD_ID_F040B:
277 printf ("AM29F040B (4 Mbit)\n");
278 break;
279 default:
280 printf ("Unknown Chip Type\n");
281 break;
282 }
283
284 if (info->size < 0x100000)
285 printf (" Size: %ld KB in %d Sectors\n",
286 info->size >> 10, info->sector_count);
287 else
288 printf (" Size: %ld MB in %d Sectors\n",
289 info->size >> 20, info->sector_count);
290
291 printf (" Sector Start Addresses:");
292 for (i = 0; i < info->sector_count; ++i) {
293 if ((i % 5) == 0)
294 printf ("\n ");
295 printf (" %08lX%s",
296 info->start[i],
297 info->protect[i] ? " (RO)" : " "
298 );
299 }
300 printf ("\n");
301}
302
303
304
305int flash_erase (flash_info_t * info, int s_first, int s_last)
306{
307 vu_char *addr = (vu_char *)(info->start[0]);
308 int flag, prot, sect, l_sect;
309 ulong start, now, last;
310
311 if ((s_first < 0) || (s_first > s_last)) {
312 if (info->flash_id == FLASH_UNKNOWN) {
313 printf ("- missing\n");
314 } else {
315 printf ("- no sectors to erase\n");
316 }
317 return 1;
318 }
319
320 prot = 0;
321 for (sect = s_first; sect <= s_last; sect++) {
322 if (info->protect[sect])
323 prot++;
324 }
325
326 if (prot) {
327 printf ("- Warning: %d protected sectors will not be erased!\n",
328 prot);
329 } else {
330 printf ("\n");
331 }
332
333
334
335 if (info->flash_id >> 16 == 0x1) {
336
337
338 l_sect = -1;
339
340
341 flag = disable_interrupts();
342
343 addr[0x0555] = 0xAA;
344 addr[0x02AA] = 0x55;
345 addr[0x0555] = 0x80;
346 addr[0x0555] = 0xAA;
347 addr[0x02AA] = 0x55;
348
349
350 udelay (1000);
351
352
353 for (sect = s_first; sect<=s_last; sect++) {
354 if (info->protect[sect] == 0) {
355 addr = (vu_char *)(info->start[sect]);
356 addr[0] = 0x30;
357 l_sect = sect;
358 }
359 }
360
361
362 if (flag)
363 enable_interrupts();
364
365
366 udelay (1000);
367
368
369
370
371 if (l_sect < 0)
372 goto AMD_DONE;
373
374 start = get_timer (0);
375 last = start;
376 addr = (vu_char *)(info->start[l_sect]);
377 while ((addr[0] & 0x80) != 0x80) {
378 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
379 printf ("Timeout\n");
380 return 1;
381 }
382
383 if ((now - last) > 1000) {
384 serial_putc ('.');
385 last = now;
386 }
387 }
388
389AMD_DONE:
390
391 addr = (volatile unsigned char *)info->start[0];
392 addr[0] = 0xF0;
393
394 } else {
395
396
397
398
399
400 for (sect = s_first; sect <= s_last; sect++) {
401 volatile ulong *addr =
402 (volatile unsigned long *) info->start[sect];
403
404 start = get_timer (0);
405 last = start;
406 if (info->protect[sect] == 0) {
407
408
409 flag = disable_interrupts ();
410
411
412
413 addr[0] = 0x00200020;
414 addr[1] = 0x00200020;
415 addr[0] = 0x00D000D0;
416 addr[1] = 0x00D000D0;
417
418
419
420 if (flag)
421 enable_interrupts ();
422
423
424
425 udelay (1000);
426
427 last = start;
428 while ((addr[0] & 0x00800080) != 0x00800080 ||
429 (addr[1] & 0x00800080) != 0x00800080) {
430 if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
431 printf ("Timeout (erase suspended!)\n");
432
433
434 addr[0] = 0x00B000B0;
435 addr[1] = 0x00B000B0;
436 goto DONE;
437 }
438
439
440 if ((now - last) > 1000) {
441 serial_putc ('.');
442 last = now;
443 }
444 }
445 if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
446 printf ("*** ERROR: erase failed!\n");
447 goto DONE;
448 }
449 }
450
451
452 addr[0] = 0x00500050;
453 addr[1] = 0x00500050;
454 addr[0] = 0x00FF00FF;
455 addr[1] = 0x00FF00FF;
456 }
457 }
458
459 printf (" done\n");
460
461DONE:
462 return 0;
463}
464
465static int write_word (flash_info_t *, volatile unsigned long *, ulong);
466static int write_byte (flash_info_t *info, ulong dest, uchar data);
467
468
469
470
471
472
473
474int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
475{
476 ulong v;
477 int i, l, rc, cc = cnt, res = 0;
478
479 if (info->flash_id >> 16 == 0x1) {
480
481
482
483 while (cnt > 0) {
484 if ((rc = write_byte(info, addr, *src)) != 0) {
485 return (rc);
486 }
487 addr++;
488 src++;
489 cnt--;
490 }
491
492 return (0);
493 } else {
494
495
496
497 for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
498 l = (addr & 3);
499 addr &= ~3;
500
501 for (i = 0; i < 4; i++) {
502 v = (v << 8) + (i < l || i - l >= cc ?
503 *((unsigned char *) addr + i) : *src++);
504 }
505
506 if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
507 break;
508 }
509 }
510
511 return (res);
512}
513
514
515
516
517
518
519
520static int write_word (flash_info_t * info, volatile unsigned long *addr,
521 ulong data)
522{
523 int flag, res = 0;
524 ulong start;
525
526
527
528 if ((*addr & data) != data)
529 return (2);
530
531
532
533 flag = disable_interrupts ();
534
535 *addr = 0x00400040;
536 *addr = data;
537
538
539
540 if (flag)
541 enable_interrupts ();
542
543 start = get_timer (0);
544 while ((*addr & 0x00800080) != 0x00800080) {
545 if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
546
547
548 *addr = 0x00B000B0;
549 res = 1;
550 goto OUT;
551 }
552 }
553
554 if (*addr & 0x00220022) {
555 printf ("*** ERROR: program failed!\n");
556 res = 1;
557 }
558
559OUT:
560
561
562 *addr = 0x00500050;
563 *addr = 0x00FF00FF;
564
565 return (res);
566}
567
568
569
570
571
572
573
574static int write_byte (flash_info_t *info, ulong dest, uchar data)
575{
576 vu_char *addr = (vu_char *)(info->start[0]);
577 ulong start;
578 int flag;
579
580
581 if ((*((vu_char *)dest) & data) != data) {
582 return (2);
583 }
584
585 flag = disable_interrupts();
586
587 addr[0x0555] = 0xAA;
588 addr[0x02AA] = 0x55;
589 addr[0x0555] = 0xA0;
590
591 *((vu_char *)dest) = data;
592
593
594 if (flag)
595 enable_interrupts();
596
597
598 start = get_timer (0);
599 while ((*((vu_char *)dest) & 0x80) != (data & 0x80)) {
600 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
601 return (1);
602 }
603 }
604 return (0);
605}
606
607
608
609