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#include <common.h>
26#include <asm/hardware.h>
27#include <flash.h>
28
29flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
30
31typedef enum {
32 FLASH_DEV_U9_512KB = 0,
33 FLASH_DEV_U7_2MB = 1
34} FLASH_DEV;
35
36#define FLASH_DQ7 (0x80)
37#define FLASH_DQ5 (0x20)
38
39#define PROG_ADDR (0xAAA)
40#define SETUP_ADDR (0xAAA)
41#define ID_ADDR (0xAAA)
42#define UNLOCK_ADDR1 (0xAAA)
43#define UNLOCK_ADDR2 (0x555)
44
45#define UNLOCK_CMD1 (0xAA)
46#define UNLOCK_CMD2 (0x55)
47#define ERASE_SUSPEND_CMD (0xB0)
48#define ERASE_RESUME_CMD (0x30)
49#define RESET_CMD (0xF0)
50#define ID_CMD (0x90)
51#define SELECT_CMD (0x90)
52#define CHIPERASE_CMD (0x10)
53#define BYPASS_CMD (0x20)
54#define SECERASE_CMD (0x30)
55#define PROG_CMD (0xa0)
56#define SETUP_CMD (0x80)
57
58#if 0
59#define WRITE_UNLOCK(addr) { \
60 PUT__U8( addr + UNLOCK_ADDR1, UNLOCK_CMD1); \
61 PUT__U8( addr + UNLOCK_ADDR2, UNLOCK_CMD2); \
62}
63
64
65#define CMD_ID(addr) WRITE_UNLOCK(addr); { \
66 PUT__U8( addr + ID_ADDR, ID_CMD); \
67}
68
69#define CMD_RESET(addr) WRITE_UNLOCK(addr); { \
70 PUT__U8( addr + ID_ADDR, RESET_CMD); \
71}
72
73#define CMD_ERASE_SEC(base, addr) WRITE_UNLOCK(base); \
74 PUT__U8( base + SETUP_ADDR, SETUP_CMD); \
75 WRITE_UNLOCK(base); \
76 PUT__U8( addr, SECERASE_CMD);
77
78#define CMD_ERASE_CHIP(base) WRITE_UNLOCK(base); \
79 PUT__U8( base + SETUP_ADDR, SETUP_CMD); \
80 WRITE_UNLOCK(base); \
81 PUT__U8( base + SETUP_ADDR, CHIPERASE_CMD);
82
83
84#define CMD_UNLOCK_BYPASS(addr) WRITE_UNLOCK(addr); { \
85 PUT__U8( addr + ID_ADDR, 0x20); \
86}
87
88
89#define CMD_BYPASS_RESET(addr) { \
90 PUT__U8(addr, 0x90); \
91 PUT__U8(addr, 0x00); \
92}
93#endif
94
95inline static void FLASH_CMD_UNLOCK (FLASH_DEV dev, u32 base)
96{
97 switch (dev) {
98 case FLASH_DEV_U7_2MB:
99 PUT__U8 (base + 0xAAA, 0xAA);
100 PUT__U8 (base + 0x555, 0x55);
101 break;
102 case FLASH_DEV_U9_512KB:
103 PUT__U8 (base + 0x555, 0xAA);
104 PUT__U8 (base + 0x2AA, 0x55);
105 break;
106 }
107}
108
109inline static void FLASH_CMD_SELECT (FLASH_DEV dev, u32 base)
110{
111 switch (dev) {
112 case FLASH_DEV_U7_2MB:
113 FLASH_CMD_UNLOCK (dev, base);
114 PUT__U8 (base + 0xAAA, SELECT_CMD);
115 break;
116 case FLASH_DEV_U9_512KB:
117 FLASH_CMD_UNLOCK (dev, base);
118 PUT__U8 (base + 0x555, SELECT_CMD);
119 break;
120 }
121}
122
123inline static void FLASH_CMD_RESET (FLASH_DEV dev, u32 base)
124{
125 switch (dev) {
126 case FLASH_DEV_U7_2MB:
127 FLASH_CMD_UNLOCK (dev, base);
128 PUT__U8 (base + 0xAAA, RESET_CMD);
129 break;
130 case FLASH_DEV_U9_512KB:
131 FLASH_CMD_UNLOCK (dev, base);
132 PUT__U8 (base + 0x555, RESET_CMD);
133 break;
134 }
135}
136
137inline static void FLASH_CMD_ERASE_SEC (FLASH_DEV dev, u32 base, u32 addr)
138{
139 switch (dev) {
140 case FLASH_DEV_U7_2MB:
141 FLASH_CMD_UNLOCK (dev, base);
142 PUT__U8 (base + 0xAAA, SETUP_CMD);
143 FLASH_CMD_UNLOCK (dev, base);
144 PUT__U8 (addr, SECERASE_CMD);
145 break;
146 case FLASH_DEV_U9_512KB:
147 FLASH_CMD_UNLOCK (dev, base);
148 PUT__U8 (base + 0x555, SETUP_CMD);
149 FLASH_CMD_UNLOCK (dev, base);
150 PUT__U8 (addr, SECERASE_CMD);
151 break;
152 }
153}
154
155inline static void FLASH_CMD_ERASE_CHIP (FLASH_DEV dev, u32 base)
156{
157 switch (dev) {
158 case FLASH_DEV_U7_2MB:
159 FLASH_CMD_UNLOCK (dev, base);
160 PUT__U8 (base + 0xAAA, SETUP_CMD);
161 FLASH_CMD_UNLOCK (dev, base);
162 PUT__U8 (base, CHIPERASE_CMD);
163 break;
164 case FLASH_DEV_U9_512KB:
165 FLASH_CMD_UNLOCK (dev, base);
166 PUT__U8 (base + 0x555, SETUP_CMD);
167 FLASH_CMD_UNLOCK (dev, base);
168 PUT__U8 (base, CHIPERASE_CMD);
169 break;
170 }
171}
172
173inline static void FLASH_CMD_UNLOCK_BYPASS (FLASH_DEV dev, u32 base)
174{
175 switch (dev) {
176 case FLASH_DEV_U7_2MB:
177 FLASH_CMD_UNLOCK (dev, base);
178 PUT__U8 (base + 0xAAA, BYPASS_CMD);
179 break;
180 case FLASH_DEV_U9_512KB:
181 FLASH_CMD_UNLOCK (dev, base);
182 PUT__U8 (base + 0x555, BYPASS_CMD);
183 break;
184 }
185}
186
187inline static void FLASH_CMD_BYPASS_RESET (FLASH_DEV dev, u32 base)
188{
189 PUT__U8 (base, SELECT_CMD);
190 PUT__U8 (base, 0x0);
191}
192
193
194static u16 _flash_poll (FLASH_DEV dev, u32 addr, u16 data, ulong timeOut)
195{
196 u32 done = 0;
197 ulong t0;
198
199 u16 error = 0;
200 volatile u16 flashData;
201
202 data = data & 0xFF;
203 t0 = get_timer (0);
204 while (get_timer (t0) < timeOut) {
205
206
207 flashData = GET__U8 (addr);
208
209
210 if ((flashData & FLASH_DQ7) == (data & FLASH_DQ7)) {
211 done = 1;
212 break;
213 }
214
215
216 if (flashData & FLASH_DQ5) {
217
218 flashData = GET__U8 (addr);
219
220
221 if (!((flashData & FLASH_DQ7) == (data & FLASH_DQ7))) {
222 printf ("_flash_poll(): FLASH_DQ7 & flashData not equal to write value\n");
223 error = ERR_PROG_ERROR;
224 }
225 FLASH_CMD_RESET (dev, addr);
226 done = 1;
227 break;
228 }
229
230 udelay (10);
231 }
232
233
234
235 if (!done) {
236 printf ("_flash_poll(): Timeout\n");
237 error = ERR_TIMOUT;
238 }
239
240
241 if (!error) {
242
243 flashData = GET__U8 (addr);
244 if (flashData != data) {
245 error = ERR_PROG_ERROR;
246 printf ("_flash_poll(): flashData(0x%04x) not equal to data(0x%04x)\n",
247 flashData, data);
248 }
249 }
250
251 return error;
252}
253
254
255
256static int _flash_check_protection (flash_info_t * info, int s_first, int s_last)
257{
258 int sect, prot = 0;
259
260 for (sect = s_first; sect <= s_last; sect++)
261 if (info->protect[sect]) {
262 printf (" Flash sector %d protected.\n", sect);
263 prot++;
264 }
265 return prot;
266}
267
268static int _detectFlash (FLASH_DEV dev, u32 base, u8 venId, u8 devId)
269{
270
271 u32 baseAddr = base | CACHE_DISABLE_MASK;
272 u8 vendorId, deviceId;
273
274
275
276
277 FLASH_CMD_SELECT (dev, baseAddr);
278 vendorId = GET__U8 (baseAddr);
279 FLASH_CMD_RESET (dev, baseAddr);
280
281
282 FLASH_CMD_SELECT (dev, baseAddr);
283
284 if (dev == FLASH_DEV_U7_2MB) {
285 deviceId = GET__U8 (baseAddr + 2);
286 } else if (dev == FLASH_DEV_U9_512KB) {
287 deviceId = GET__U8 (baseAddr + 1);
288 } else {
289 return 0;
290 }
291
292 FLASH_CMD_RESET (dev, baseAddr);
293
294
295
296
297
298 return (vendorId == venId) && (deviceId == devId);
299
300}
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322unsigned long flash_init (void)
323{
324 flash_info_t *info;
325 u16 i;
326 u32 flashtest;
327 s16 amd160 = -1;
328 u32 amd160base = 0;
329
330#if CONFIG_SYS_MAX_FLASH_BANKS == 2
331 s16 amd040 = -1;
332 u32 amd040base = 0;
333#endif
334
335
336 if (_detectFlash (FLASH_DEV_U7_2MB, PHYS_FLASH_1, 0x1, 0x49)) {
337 amd160 = 0;
338 amd160base = PHYS_FLASH_1;
339#if CONFIG_SYS_MAX_FLASH_BANKS == 1
340 }
341#else
342 if (_detectFlash
343 (FLASH_DEV_U9_512KB, PHYS_FLASH_2, 0x1, 0x4F)) {
344 amd040 = 1;
345 amd040base = PHYS_FLASH_2;
346 } else {
347 printf (__FUNCTION__
348 "(): Unable to detect PHYS_FLASH_2: 0x%08x\n",
349 PHYS_FLASH_2);
350 }
351 } else if (_detectFlash (FLASH_DEV_U9_512KB, PHYS_FLASH_1, 0x1, 0x4F)) {
352 amd040 = 0;
353 amd040base = PHYS_FLASH_1;
354 if (_detectFlash (FLASH_DEV_U7_2MB, PHYS_FLASH_2, 0x1, 0x49)) {
355 amd160 = 1;
356 amd160base = PHYS_FLASH_2;
357 } else {
358 printf (__FUNCTION__
359 "(): Unable to detect PHYS_FLASH_2: 0x%08x\n",
360 PHYS_FLASH_2);
361 }
362 }
363#endif
364 else {
365 printf ("flash_init(): Unable to detect PHYS_FLASH_1: 0x%08x\n",
366 PHYS_FLASH_1);
367 }
368
369
370 info = &flash_info[amd160];
371 info->flash_id = FLASH_DEV_U7_2MB;
372 info->sector_count = 35;
373 info->size = 2 * 1024 * 1024;
374
375
376
377 info->start[0] = amd160base;
378 info->start[1] = amd160base + 0x4000;
379 info->start[2] = amd160base + 0x6000;
380 info->start[3] = amd160base + 0x8000;
381 for (i = 1; i < info->sector_count; i++)
382 info->start[3 + i] = amd160base + i * (64 * 1024);
383
384 for (i = 0; i < info->sector_count; i++) {
385
386 FLASH_CMD_SELECT (info->flash_id,
387 info->start[i] | CACHE_DISABLE_MASK);
388 flashtest =
389 GET__U8 (((info->start[i] + 4) | CACHE_DISABLE_MASK));
390 FLASH_CMD_RESET (info->flash_id,
391 amd160base | CACHE_DISABLE_MASK);
392 info->protect[i] = (flashtest & 0x0001);
393 }
394
395
396
397
398 flash_protect (FLAG_PROTECT_SET,
399 amd160base, amd160base + monitor_flash_len - 1, info);
400
401 flash_protect (FLAG_PROTECT_SET,
402 CONFIG_ENV_ADDR, CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, info);
403
404#if CONFIG_SYS_MAX_FLASH_BANKS == 2
405
406 info = &flash_info[amd040];
407 info->flash_id = FLASH_DEV_U9_512KB;
408 info->sector_count = 8;
409 info->size = 512 * 1024;
410 for (i = 0; i < info->sector_count; i++) {
411 info->start[i] = amd040base + i * (64 * 1024);
412
413 FLASH_CMD_SELECT (info->flash_id,
414 info->start[i] | CACHE_DISABLE_MASK);
415 flashtest =
416 GET__U8 (((info->start[i] + 2) | CACHE_DISABLE_MASK));
417 FLASH_CMD_RESET (info->flash_id,
418 amd040base | CACHE_DISABLE_MASK);
419 info->protect[i] = (flashtest & 0x0001);
420 }
421#endif
422
423 return flash_info[0].size
424#if CONFIG_SYS_MAX_FLASH_BANKS == 2
425 + flash_info[1].size
426#endif
427 ;
428}
429
430void flash_print_info (flash_info_t * info)
431{
432 int i;
433
434 if (info->flash_id == FLASH_DEV_U7_2MB) {
435 printf ("AMD Am29LV160DB (2MB) 16KB,2x8KB,32KB,31x64KB\n");
436 } else if (info->flash_id == FLASH_DEV_U9_512KB) {
437 printf ("AMD Am29LV040B (512KB) 8x64KB\n");
438 } else {
439 printf ("Unknown flash_id ...\n");
440 return;
441 }
442
443 printf (" Size: %ld KB in %d Sectors\n",
444 info->size >> 10, info->sector_count);
445 printf (" Sector Start Addresses:");
446 for (i = 0; i < info->sector_count; i++) {
447 if ((i % 4) == 0)
448 printf ("\n ");
449 printf (" S%02d @ 0x%08lX%s", i,
450 info->start[i], info->protect[i] ? " !" : " ");
451 }
452 printf ("\n");
453}
454
455int flash_erase (flash_info_t * info, int s_first, int s_last)
456{
457 u16 i, error = 0;
458
459 printf ("\n");
460
461
462 if (_flash_check_protection (info, s_first, s_last)) {
463 printf (" Flash erase aborted due to protected sectors\n");
464 return ERR_PROTECTED;
465 }
466
467 if ((s_first < info->sector_count) && (s_first <= s_last)) {
468 for (i = s_first; i <= s_last && !error; i++) {
469 printf (" Erasing Sector %d @ 0x%08lx ... ", i,
470 info->start[i]);
471
472 FLASH_CMD_ERASE_SEC (info->flash_id,
473 (info->
474 start[0] | CACHE_DISABLE_MASK),
475 (info->
476 start[i] | CACHE_DISABLE_MASK));
477
478 error = _flash_poll (info->flash_id,
479 info->
480 start[i] | CACHE_DISABLE_MASK,
481 0xFF, CONFIG_SYS_FLASH_ERASE_TOUT);
482 FLASH_CMD_RESET (info->flash_id,
483 (info->
484 start[0] | CACHE_DISABLE_MASK));
485 printf ("done\n");
486 if (error) {
487 break;
488 }
489 }
490 } else
491 error = ERR_INVAL;
492
493 return error;
494}
495
496int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
497{
498 u16 error = 0, i;
499 u32 n;
500 u8 *bp, *bps;
501
502
503
504 FLASH_CMD_UNLOCK_BYPASS (info->flash_id,
505 (info->start[0] | CACHE_DISABLE_MASK));
506
507
508
509 bp = (u8 *) (addr | CACHE_DISABLE_MASK);
510 bps = (u8 *) src;
511
512 for (n = 0; n < cnt && !error; n++, bp++, bps++) {
513
514 if (!(n % (cnt / 15))) {
515 printf (".");
516 }
517
518
519 *bp = 0xA0;
520
521
522 *bp = *bps;
523
524
525 for (i = 0; i < 0xff; i++);
526 error = _flash_poll (info->flash_id, (u32) bp, *bps,
527 CONFIG_SYS_FLASH_WRITE_TOUT);
528 if (error) {
529 return error;
530 }
531 }
532
533
534 FLASH_CMD_BYPASS_RESET (info->flash_id, info->start[0]);
535
536 printf (" ");
537
538 return error;
539}
540