1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54#include <common.h>
55#include <mpc8260.h>
56
57flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
58
59static ulong flash_get_size (vu_long *addr, flash_info_t *info);
60static int write_word (flash_info_t *info, ulong dest, ulong data);
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79unsigned long flash_init (void)
80{
81 unsigned long size;
82 int i;
83
84
85 for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
86 flash_info[i].flash_id = FLASH_UNKNOWN;
87 }
88
89
90 size = flash_get_size((vu_long *)CONFIG_SYS_FLASH0_BASE, &flash_info[0]);
91
92
93
94
95
96#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH0_BASE
97 flash_protect(FLAG_PROTECT_SET,
98 CONFIG_SYS_MONITOR_BASE,
99 CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
100 &flash_info[0]);
101#endif
102
103#if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR)
104# ifndef CONFIG_ENV_SIZE
105# define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
106# endif
107 flash_protect(FLAG_PROTECT_SET,
108 CONFIG_ENV_ADDR,
109 CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
110 &flash_info[0]);
111#endif
112
113 return (CONFIG_SYS_FLASH0_SIZE * 1024 * 1024);
114}
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135void flash_print_info (flash_info_t *info)
136{
137 int i;
138
139 if (info->flash_id == FLASH_UNKNOWN) {
140 printf ("missing or unknown FLASH type\n");
141 return;
142 }
143
144 switch ((info->flash_id >> 16) & 0xff) {
145 case 0x1:
146 printf ("AMD ");
147 break;
148 default:
149 printf ("Unknown Vendor ");
150 break;
151 }
152
153 switch (info->flash_id & FLASH_TYPEMASK) {
154 case AMD_ID_F040B:
155 printf ("AM29F040B (4 Mbit)\n");
156 break;
157 case AMD_ID_F080B:
158 printf ("AM29F080B (8 Mbit)\n");
159 break;
160 case AMD_ID_F016D:
161 printf ("AM29F016D (16 Mbit)\n");
162 break;
163 default:
164 printf ("Unknown Chip Type\n");
165 break;
166 }
167
168 printf (" Size: %ld MB in %d Sectors\n",
169 info->size >> 20, info->sector_count);
170
171 printf (" Sector Start Addresses:");
172 for (i=0; i<info->sector_count; ++i) {
173 if ((i % 5) == 0)
174 printf ("\n ");
175 printf (" %08lX%s",
176 info->start[i],
177 info->protect[i] ? " (RO)" : " "
178 );
179 }
180 printf ("\n");
181 return;
182}
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212static ulong flash_get_size (vu_long *addr, flash_info_t *info)
213{
214 short i;
215 vu_long vendor, devid;
216 ulong base = (ulong)addr;
217
218
219
220
221 addr[0x0000] = 0xf0f0f0f0;
222 addr[0x0555] = 0xAAAAAAAA;
223 addr[0x02AA] = 0x55555555;
224 addr[0x0555] = 0x90909090;
225 udelay (1000);
226
227 vendor = addr[0];
228
229 if (vendor != 0x01010101) {
230 info->size = 0;
231 goto out;
232 }
233
234 devid = addr[1];
235
236
237 if ((devid & 0xff) == AMD_ID_F080B) {
238 info->flash_id = (vendor & 0xff) << 16 | AMD_ID_F080B;
239
240 info->sector_count = 16;
241 info->size = 4 * info->sector_count * 64*1024;
242 } else if ((devid & 0xff) == AMD_ID_F016D){
243 info->flash_id = (vendor & 0xff) << 16 | AMD_ID_F016D;
244
245 info->sector_count = 32;
246 info->size = 4 * info->sector_count * 64*1024;
247 } else {
248 info->size = 0;
249 goto out;
250 }
251
252
253 for (i = 0; i < info->sector_count; i++) {
254
255 info->start[i] = base + i * (info->size / info->sector_count);
256
257
258 addr = (volatile unsigned long *)(info->start[i]);
259 info->protect[i] = addr[2] & 1;
260 }
261
262
263 addr = (vu_long *)info->start[0];
264
265 out:
266 addr[0] = 0xf0f0f0f0;
267
268
269 return info->size;
270}
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293int flash_erase (flash_info_t *info, int s_first, int s_last)
294{
295 vu_long *addr = (vu_long*)(info->start[0]);
296 int flag, prot, sect, l_sect;
297 ulong start, now, last;
298
299 if ((s_first < 0) || (s_first > s_last)) {
300 if (info->flash_id == FLASH_UNKNOWN) {
301 printf ("- missing\n");
302 } else {
303 printf ("- no sectors to erase\n");
304 }
305 return 1;
306 }
307
308 prot = 0;
309 for (sect = s_first; sect <= s_last; sect++) {
310 if (info->protect[sect]) {
311 prot++;
312 }
313 }
314
315 if (prot) {
316 printf ("- Warning: %d protected sectors will not be erased!\n",
317 prot);
318 } else {
319 printf ("\n");
320 }
321
322 l_sect = -1;
323
324
325 flag = disable_interrupts();
326
327 addr[0x0555] = 0xAAAAAAAA;
328 addr[0x02AA] = 0x55555555;
329 addr[0x0555] = 0x80808080;
330 addr[0x0555] = 0xAAAAAAAA;
331 addr[0x02AA] = 0x55555555;
332 udelay (100);
333
334
335 for (sect = s_first; sect <= s_last; sect++) {
336 if (info->protect[sect] == 0) {
337 addr = (vu_long*)(info->start[sect]);
338 addr[0] = 0x30303030;
339 l_sect = sect;
340 }
341 }
342
343
344 if (flag)
345 enable_interrupts();
346
347
348 udelay (1000);
349
350
351
352
353 if (l_sect < 0)
354 goto DONE;
355
356 start = get_timer (0);
357 last = start;
358 addr = (vu_long*)(info->start[l_sect]);
359 while ((addr[0] & 0x80808080) != 0x80808080) {
360 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
361 printf ("Timeout\n");
362 return 1;
363 }
364
365 if ((now - last) > 1000) {
366 serial_putc ('.');
367 last = now;
368 }
369 }
370
371 DONE:
372
373 addr = (volatile unsigned long *)info->start[0];
374 addr[0] = 0xF0F0F0F0;
375
376 printf (" done\n");
377 return 0;
378}
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
404{
405 ulong cp, wp, data;
406 int i, l, rc;
407
408 wp = (addr & ~3);
409
410
411
412
413 if ((l = addr - wp) != 0) {
414 data = 0;
415 for (i = 0, cp = wp; i < l; ++i, ++cp) {
416 data = (data << 8) | (*(uchar *)cp);
417 }
418 for (; (i < 4) && (cnt > 0); ++i) {
419 data = (data << 8) | *src++;
420 --cnt;
421 ++cp;
422 }
423 for (; (cnt == 0) && (i < 4); ++i, ++cp) {
424 data = (data << 8) | (*(uchar *)cp);
425 }
426
427 if ((rc = write_word(info, wp, data)) != 0) {
428 return (rc);
429 }
430 wp += 4;
431 }
432
433
434
435
436 while (cnt >= 4) {
437 data = 0;
438 for (i = 0; i < 4; ++i) {
439 data = (data << 8) | *src++;
440 }
441 if ((rc = write_word(info, wp, data)) != 0) {
442 return (rc);
443 }
444 wp += 4;
445 cnt -= 4;
446 }
447
448 if (cnt == 0) {
449 return (0);
450 }
451
452
453
454
455 data = 0;
456 for (i = 0, cp = wp; (i < 4) && (cnt > 0); ++i, ++cp) {
457 data = (data << 8) | *src++;
458 --cnt;
459 }
460 for (; (i < 4); ++i, ++cp) {
461 data = (data << 8) | (*(uchar *)cp);
462 }
463
464 return (write_word(info, wp, data));
465}
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489static int write_word (flash_info_t *info, ulong dest, ulong data)
490{
491 vu_long *addr = (vu_long*)(info->start[0]);
492 ulong start;
493 int flag;
494
495
496 if ((*((vu_long *)dest) & data) != data) {
497 return (2);
498 }
499
500 flag = disable_interrupts();
501
502 addr[0x0555] = 0xAAAAAAAA;
503 addr[0x02AA] = 0x55555555;
504 addr[0x0555] = 0xA0A0A0A0;
505
506 *((vu_long *)dest) = data;
507
508
509 if (flag)
510 enable_interrupts();
511
512
513 start = get_timer (0);
514 while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
515 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
516 return (1);
517 }
518 }
519 return (0);
520}
521
522
523
524