1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25
26flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
27
28typedef unsigned short FLASH_PORT_WIDTH;
29typedef volatile unsigned short FLASH_PORT_WIDTHV;
30
31#define FLASH_ID_MASK 0x00FF
32
33#define FPW FLASH_PORT_WIDTH
34#define FPWV FLASH_PORT_WIDTHV
35
36#define FLASH_CYCLE1 0x0555
37#define FLASH_CYCLE2 0x0aaa
38#define FLASH_ID1 0x00
39#define FLASH_ID2 0x01
40#define FLASH_ID3 0x0E
41#define FLASH_ID4 0x0F
42
43
44
45
46static ulong flash_get_size(FPWV * addr, flash_info_t * info);
47static void flash_reset(flash_info_t * info);
48static int write_word_amd(flash_info_t * info, FPWV * dest, FPW data);
49static flash_info_t *flash_get_info(ulong base);
50
51
52
53
54
55
56unsigned long flash_init(void)
57{
58 unsigned long size = 0;
59 int i = 0;
60 extern void flash_preinit(void);
61 extern void flash_afterinit(uint, ulong, ulong);
62
63 ulong flashbase = CONFIG_SYS_FLASH_BASE;
64
65 flash_preinit();
66
67
68 memset(&flash_info[i], 0, sizeof(flash_info_t));
69 flash_info[i].size = flash_get_size((FPW *) flashbase, &flash_info[i]);
70 size += flash_info[i].size;
71
72#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
73
74 flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
75 CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
76 flash_get_info(CONFIG_SYS_MONITOR_BASE));
77#endif
78
79#ifdef CONFIG_ENV_IS_IN_FLASH
80
81 flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
82 CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
83 flash_get_info(CONFIG_ENV_ADDR));
84#endif
85
86 flash_afterinit(i, flash_info[i].start[0], flash_info[i].size);
87 return size ? size : 1;
88}
89
90
91
92static void flash_reset(flash_info_t * info) {
93 FPWV *base = (FPWV *) (info->start[0]);
94
95
96 if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
97 *base = (FPW) 0x00FF00FF;
98 } else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
99 *base = (FPW) 0x00F000F0;
100 }
101}
102
103
104
105
106static flash_info_t *flash_get_info(ulong base) {
107 int i;
108 flash_info_t *info;
109
110 for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
111 info = &flash_info[i];
112 if ((info->size) && (info->start[0] <= base)
113 && (base <= info->start[0] + info->size - 1)) {
114 break;
115 }
116 }
117 return (i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info);
118}
119
120
121
122
123void flash_print_info(flash_info_t * info) {
124 int i;
125 char *fmt;
126
127 if (info->flash_id == FLASH_UNKNOWN) {
128 printf("missing or unknown FLASH type\n");
129 return;
130 }
131
132 switch (info->flash_id & FLASH_VENDMASK) {
133 case FLASH_MAN_AMD:
134 printf("AMD ");
135 break;
136 default:
137 printf("Unknown Vendor ");
138 break;
139 }
140
141 switch (info->flash_id & FLASH_TYPEMASK) {
142 case FLASH_AMLV256U:
143 fmt = "29LV256M (256 Mbit)\n";
144 break;
145 default:
146 fmt = "Unknown Chip Type\n";
147 break;
148 }
149
150 printf(fmt);
151 printf(" Size: %ld MB in %d Sectors\n", info->size >> 20,
152 info->sector_count);
153 printf(" Sector Start Addresses:");
154
155 for (i = 0; i < info->sector_count; ++i) {
156 ulong size;
157 int erased;
158 ulong *flash = (unsigned long *)info->start[i];
159
160 if ((i % 5) == 0) {
161 printf("\n ");
162 }
163
164
165
166
167 size =
168 (i !=
169 (info->sector_count - 1)) ? (info->start[i + 1] -
170 info->start[i]) >> 2 : (info->
171 start
172 [0] +
173 info->
174 size -
175 info->
176 start
177 [i])
178 >> 2;
179
180 for (flash = (unsigned long *)info->start[i], erased = 1;
181 (flash != (unsigned long *)info->start[i] + size)
182 && erased; flash++) {
183 erased = *flash == ~0x0UL;
184 }
185 printf(" %08lX %s %s", info->start[i], erased ? "E" : " ",
186 info->protect[i] ? "(RO)" : " ");
187 }
188
189 printf("\n");
190}
191
192
193
194
195
196
197
198
199ulong flash_get_size(FPWV * addr, flash_info_t * info) {
200 int i;
201
202
203
204 addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA;
205 addr[FLASH_CYCLE2] = (FPW) 0x00550055;
206 addr[FLASH_CYCLE1] = (FPW) 0x00900090;
207
208
209
210 udelay(100);
211 switch (addr[FLASH_ID1] & 0x00ff) {
212 case (uchar) AMD_MANUFACT:
213 info->flash_id = FLASH_MAN_AMD;
214 break;
215 default:
216 printf("unknown vendor=%x ", addr[FLASH_ID1] & 0xff);
217 info->flash_id = FLASH_UNKNOWN;
218 info->sector_count = 0;
219 info->size = 0;
220 break;
221 }
222
223
224 if (info->flash_id != FLASH_UNKNOWN) {
225 switch ((FPW) addr[FLASH_ID2]) {
226 case (FPW) AMD_ID_MIRROR:
227
228 if ((FPW) addr[FLASH_ID3] == (FPW) AMD_ID_LV256U_2
229 && (FPW) addr[FLASH_ID4] == (FPW) AMD_ID_LV256U_3) {
230
231 info->flash_id += FLASH_AMLV256U;
232 info->sector_count = 512;
233 info->size = 0x02000000;
234 for (i = 0; i < info->sector_count; i++) {
235 info->start[i] =
236 (ulong) addr + 0x10000 * i;
237 }
238 break;
239 }
240
241 default:
242 printf("unknown AMD device=%x %x %x",
243 (FPW) addr[FLASH_ID2], (FPW) addr[FLASH_ID3],
244 (FPW) addr[FLASH_ID4]);
245 info->flash_id = FLASH_UNKNOWN;
246 info->sector_count = 0;
247 info->size = 0x800000;
248 break;
249 }
250
251
252 flash_reset(info);
253 }
254 return (info->size);
255}
256
257
258
259
260int flash_erase(flash_info_t * info, int s_first, int s_last) {
261 FPWV *addr;
262 int flag, prot, sect;
263 int intel = (info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL;
264 ulong start, now, last;
265 int rcode = 0;
266
267 if ((s_first < 0) || (s_first > s_last)) {
268 if (info->flash_id == FLASH_UNKNOWN) {
269 printf("- missing\n");
270 } else {
271 printf("- no sectors to erase\n");
272 }
273 return 1;
274 }
275
276 switch (info->flash_id & FLASH_TYPEMASK) {
277 case FLASH_AMLV256U:
278 break;
279 case FLASH_UNKNOWN:
280 default:
281 printf("Can't erase unknown flash type %08lx - aborted\n",
282 info->flash_id);
283 return 1;
284 }
285
286 prot = 0;
287 for (sect = s_first; sect <= s_last; ++sect) {
288 if (info->protect[sect]) {
289 prot++;
290 }
291 }
292
293 if (prot) {
294 printf("- Warning: %d protected sectors will not be erased!\n",
295 prot);
296 } else {
297 printf("\n");
298 }
299
300 last = get_timer(0);
301
302
303 for (sect = s_first; sect <= s_last && rcode == 0; sect++) {
304 if (info->protect[sect] != 0) {
305 continue;
306 }
307
308 flag = disable_interrupts();
309
310 addr = (FPWV *) (info->start[sect]);
311 if (intel) {
312 *addr = (FPW) 0x00500050;
313 *addr = (FPW) 0x00200020;
314 *addr = (FPW) 0x00D000D0;
315 } else {
316
317 FPWV *base;
318
319 base = (FPWV *) (info->start[0]);
320 base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;
321 base[FLASH_CYCLE2] = (FPW) 0x00550055;
322 base[FLASH_CYCLE1] = (FPW) 0x00800080;
323 base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;
324 base[FLASH_CYCLE2] = (FPW) 0x00550055;
325 *addr = (FPW) 0x00300030;
326 }
327
328
329 if (flag) {
330 enable_interrupts();
331 }
332 start = get_timer(0);
333
334
335
336 udelay(1000);
337
338 while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
339 if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
340 printf("Timeout\n");
341 if (intel) {
342
343 *addr = (FPW) 0x00B000B0;
344 }
345 flash_reset(info);
346 rcode = 1;
347 break;
348 }
349
350 if ((get_timer(last)) > CONFIG_SYS_HZ) {
351
352 putc('.');
353 last = get_timer(0);
354 }
355 }
356
357 if ((get_timer(last)) > CONFIG_SYS_HZ) {
358
359 putc('.');
360 last = get_timer(0);
361 }
362 flash_reset(info);
363 }
364 printf(" done\n");
365 return (rcode);
366}
367
368
369
370
371
372
373
374int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
375{
376 FPW data = 0;
377 int bytes;
378 int left;
379 int i, res;
380
381 for (left = cnt, res = 0;
382 left > 0 && res == 0;
383 addr += sizeof(data), left -= sizeof(data) - bytes) {
384
385 bytes = addr & (sizeof(data) - 1);
386 addr &= ~(sizeof(data) - 1);
387
388
389
390
391 for (i = 0; i < sizeof(data); i++) {
392 data <<= 8;
393 if (i < bytes || i - bytes >= left)
394 data += *((uchar *) addr + i);
395 else
396 data += *src++;
397 }
398
399
400 switch (info->flash_id & FLASH_VENDMASK) {
401 case FLASH_MAN_AMD:
402 res = write_word_amd(info, (FPWV *) addr, data);
403 break;
404 default:
405
406 printf("missing or unknown FLASH type\n");
407 res = 1;
408 break;
409 }
410 }
411 return (res);
412}
413
414
415
416
417
418
419
420
421
422
423
424static int write_word_amd(flash_info_t * info, FPWV * dest, FPW data) {
425 ulong start;
426 int flag;
427 int res = 0;
428 FPWV *base;
429
430
431 if ((*dest & data) != data) {
432 return (2);
433 }
434
435 base = (FPWV *) (info->start[0]);
436
437
438 flag = disable_interrupts();
439
440 base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;
441 base[FLASH_CYCLE2] = (FPW) 0x00550055;
442 base[FLASH_CYCLE1] = (FPW) 0x00A000A0;
443
444 *dest = data;
445
446
447 if (flag) {
448 enable_interrupts();
449 }
450 start = get_timer(0);
451
452
453 while (res == 0
454 && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
455 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
456 *dest = (FPW) 0x00F000F0;
457 res = 1;
458 }
459 }
460 return (res);
461}
462