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#include <common.h>
34#include <mpc8xx.h>
35
36flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
37
38
39
40
41static ulong flash_get_size (vu_long *addr, flash_info_t *info);
42static int write_word (flash_info_t *info, ulong dest, ulong data);
43static void flash_get_offsets (ulong base, flash_info_t *info);
44
45
46
47
48unsigned long flash_init (void)
49{
50 unsigned long size_b0 ;
51 int i;
52
53
54 for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
55 flash_info[i].flash_id = FLASH_UNKNOWN;
56 }
57
58 size_b0 = flash_get_size((vu_long *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
59
60
61 flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[0]);
62
63#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
64
65 flash_protect(FLAG_PROTECT_SET,
66 CONFIG_SYS_MONITOR_BASE,
67 CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
68 &flash_info[0]);
69#endif
70
71 flash_info[0].size = size_b0;
72
73 return (size_b0);
74}
75
76
77
78static void flash_get_offsets (ulong base, flash_info_t *info)
79{
80 int i;
81
82 if (info->flash_id & FLASH_BTYPE) {
83
84 info->start[0] = base + 0x00000000;
85 info->start[1] = base + 0x00008000;
86 info->start[2] = base + 0x00010000;
87 info->start[3] = base + 0x00018000;
88 info->start[4] = base + 0x00020000;
89 info->start[5] = base + 0x00028000;
90 info->start[6] = base + 0x00030000;
91 info->start[7] = base + 0x00038000;
92 for (i = 8; i < info->sector_count; i++) {
93 info->start[i] = base + ((i-7) * 0x00040000) ;
94 }
95 }
96}
97
98
99
100void flash_print_info (flash_info_t *info)
101{
102 int i;
103
104 if (info->flash_id == FLASH_UNKNOWN) {
105 printf ("missing or unknown FLASH type\n");
106 return;
107 }
108
109 switch (info->flash_id & FLASH_VENDMASK) {
110 case FLASH_MAN_AMD: printf ("AMD "); break;
111 default: printf ("Unknown Vendor "); break;
112 }
113
114 switch (info->flash_id & FLASH_TYPEMASK) {
115 case FLASH_AMDL323B:
116 printf ("AMDL323DB (16 Mbytes, bottom boot sect)\n");
117 break;
118 default:
119 printf ("Unknown Chip Type\n");
120 break;
121 }
122
123 printf (" Size: %ld MB in %d Sectors\n",
124 info->size >> 20, info->sector_count);
125
126 printf (" Sector Start Addresses:");
127 for (i=0; i<info->sector_count; ++i) {
128 if ((i % 5) == 0)
129 printf ("\n ");
130 printf (" %08lX%s",
131 info->start[i],
132 info->protect[i] ? " (RO)" : " "
133 );
134 }
135 printf ("\n");
136}
137
138
139
140
141
142
143
144
145
146
147
148
149static ulong flash_get_size (vu_long *addr, flash_info_t *info)
150{
151 short i;
152 ulong value;
153 ulong base = (ulong)addr;
154
155
156 addr [0] = 0xf0f0f0f0;
157
158
159 addr[0xAAA] = 0xAAAAAAAA ;
160 addr[0x555] = 0x55555555 ;
161 addr[0xAAA] = 0x90909090 ;
162
163 value = addr[0] ;
164
165 switch (value & 0x00FF00FF) {
166 case AMD_MANUFACT:
167 info->flash_id = FLASH_MAN_AMD;
168 break;
169 default:
170 info->flash_id = FLASH_UNKNOWN;
171 info->sector_count = 0;
172 info->size = 0;
173 return (0);
174 }
175
176 value = addr[2] ;
177
178 switch (value & 0x00FF00FF) {
179 case (AMD_ID_DL323B & 0x00FF00FF):
180 info->flash_id += FLASH_AMDL323B;
181 info->sector_count = 71;
182 info->size = 0x01000000;
183
184 break;
185 default:
186 info->flash_id = FLASH_UNKNOWN;
187 return (0);
188
189 }
190
191
192 info->start[0] = base + 0x00000000;
193 info->start[1] = base + 0x00008000;
194 info->start[2] = base + 0x00010000;
195 info->start[3] = base + 0x00018000;
196 info->start[4] = base + 0x00020000;
197 info->start[5] = base + 0x00028000;
198 info->start[6] = base + 0x00030000;
199 info->start[7] = base + 0x00038000;
200 for (i = 8; i < info->sector_count; i++) {
201 info->start[i] = base + ((i-7) * 0x00040000) ;
202 }
203
204
205 for (i = 0; i < 23; i++) {
206
207
208 addr = (volatile unsigned long *)(info->start[i]);
209 info->protect[i] = addr[4] & 1 ;
210 }
211
212 addr[0x100AAA] = 0xAAAAAAAA ;
213 addr[0x100555] = 0x55555555 ;
214 addr[0x100AAA] = 0x90909090 ;
215
216 for (i = 23; i < info->sector_count; i++) {
217
218
219 addr = (volatile unsigned long *)(info->start[i]);
220 info->protect[i] = addr[4] & 1 ;
221 }
222
223
224
225
226 if (info->flash_id != FLASH_UNKNOWN) {
227 addr = (volatile unsigned long *)info->start[0];
228
229 *addr = 0xF0F0F0F0;
230 addr = (volatile unsigned long *)info->start[23];
231
232 *addr = 0xF0F0F0F0;
233
234 }
235
236 return (info->size);
237}
238
239
240
241
242
243int flash_erase (flash_info_t *info, int s_first, int s_last)
244{
245 vu_long *addr = (vu_long*)(info->start[0]);
246 int flag, prot, sect, l_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_UNKNOWN) ||
259 (info->flash_id > FLASH_AMD_COMP)) {
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 l_sect = -1;
280
281
282 flag = disable_interrupts();
283
284 addr[0xAAA] = 0xAAAAAAAA;
285 addr[0x555] = 0x55555555;
286 addr[0xAAA] = 0x80808080;
287 addr[0xAAA] = 0xAAAAAAAA;
288 addr[0x555] = 0x55555555;
289
290
291 for (sect = s_first; sect<=s_last; sect++) {
292 if (info->protect[sect] == 0) {
293 addr = (vu_long *)(info->start[sect]) ;
294 addr[0] = 0x30303030 ;
295 l_sect = sect;
296 }
297 }
298
299
300 if (flag)
301 enable_interrupts();
302
303
304 udelay (1000);
305
306
307
308
309 if (l_sect < 0)
310 goto DONE;
311
312 start = get_timer (0);
313 last = start;
314 addr = (vu_long *)(info->start[l_sect]);
315 while ((addr[0] & 0x80808080) != 0x80808080) {
316 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
317 printf ("Timeout\n");
318 return 1;
319 }
320
321 if ((now - last) > 1000) {
322 putc ('.');
323 last = now;
324 }
325 }
326
327DONE:
328
329 addr = (vu_long *)info->start[0];
330 addr[0] = 0xF0F0F0F0;
331
332 printf (" done\n");
333 return 0;
334}
335
336
337
338
339
340
341
342
343int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
344{
345 ulong cp, wp, data;
346 int i, l, rc;
347
348 wp = (addr & ~3);
349
350
351
352
353 if ((l = addr - wp) != 0) {
354 data = 0;
355 for (i=0, cp=wp; i<l; ++i, ++cp) {
356 data = (data << 8) | (*(uchar *)cp);
357 }
358 for (; i<4 && cnt>0; ++i) {
359 data = (data << 8) | *src++;
360 --cnt;
361 ++cp;
362 }
363 for (; cnt==0 && i<4; ++i, ++cp) {
364 data = (data << 8) | (*(uchar *)cp);
365 }
366
367 if ((rc = write_word(info, wp, data)) != 0) {
368 return (rc);
369 }
370 wp += 4;
371 }
372
373
374
375
376 while (cnt >= 4) {
377 data = 0;
378 for (i=0; i<4; ++i) {
379 data = (data << 8) | *src++;
380 }
381 if ((rc = write_word(info, wp, data)) != 0) {
382 return (rc);
383 }
384 wp += 4;
385 cnt -= 4;
386 }
387
388 if (cnt == 0) {
389 return (0);
390 }
391
392
393
394
395 data = 0;
396 for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
397 data = (data << 8) | *src++;
398 --cnt;
399 }
400 for (; i<4; ++i, ++cp) {
401 data = (data << 8) | (*(uchar *)cp);
402 }
403
404 return (write_word(info, wp, data));
405}
406
407
408
409
410
411
412
413static int write_word (flash_info_t *info, ulong dest, ulong data)
414{
415 vu_long *addr = (vu_long *)(info->start[0]);
416 ulong start;
417 int flag;
418
419
420 if ((*((vu_long *)dest) & data) != data) {
421 return (2);
422 }
423
424 flag = disable_interrupts();
425
426 addr[0xAAA] = 0xAAAAAAAA;
427 addr[0x555] = 0x55555555;
428 addr[0xAAA] = 0xA0A0A0A0;
429
430 *((vu_long *)dest) = data;
431
432
433 if (flag)
434 enable_interrupts();
435
436
437 start = get_timer (0);
438 while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
439 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
440 return (1);
441 }
442 }
443 return (0);
444}
445
446
447
448