3
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4
* (C) Copyright 2001-2003
6
* Changes for MATRIX Vision mvBLUE devices
7
* MATRIX Vision GmbH / hg,as info@matrix-vision.de
9
* SPDX-License-Identifier: GPL-2.0+
16
#define mvdebug(p) printf ##p
21
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
23
#define FLASH_BUS_WIDTH 8
25
#if (FLASH_BUS_WIDTH==32)
26
#define FLASH_DATA_MASK 0xffffffff
29
#elif (FLASH_BUS_WIDTH==16)
30
#define FLASH_DATA_MASK 0xff
33
#elif (FLASH_BUS_WIDTH==8)
34
#define FLASH_DATA_MASK 0xff
38
#error FLASH_BUS_WIDTH undefined
41
/*-----------------------------------------------------------------------
44
static ulong flash_get_size (vu_long *address, flash_info_t *info);
45
static int write_word (flash_info_t *info, ulong dest, ulong data);
46
static void flash_get_offsets (ulong base, flash_info_t *info);
48
/*-----------------------------------------------------------------------
50
unsigned long flash_init (void)
52
unsigned long size_b0;
55
for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
56
flash_info[i].flash_id = FLASH_UNKNOWN;
59
size_b0 = flash_get_size((vu_long *)0xffc00000, &flash_info[0]);
61
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
62
printf ("## Unknown FLASH : Size = 0x%08lx = %ld MB\n",
63
size_b0, size_b0<<20);
66
flash_get_offsets (0xffc00000, &flash_info[0]);
67
flash_info[0].size = size_b0;
69
/* monitor protection OFF by default */
70
flash_protect ( FLAG_PROTECT_CLEAR, 0xffc00000, 0x2000, flash_info );
75
/*-----------------------------------------------------------------------
77
static void flash_get_offsets (ulong base, flash_info_t *info)
81
/* set up sector start address table */
82
if (info->flash_id & FLASH_BTYPE)
83
{ /* bottom boot sector types - these are the useful ones! */
84
/* set sector offsets for bottom boot block type */
85
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B)
86
{ /* AMDLV320B has 8 x 8k bottom boot sectors */
87
for (i = 0; i < 8; i++) /* +8k */
88
info->start[i] = base + (i * (0x00002000 << FLASH_SHIFT));
89
for (; i < info->sector_count; i++) /* +64k */
90
info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT)) - (0x00070000 << FLASH_SHIFT);
93
{ /* other types have 4 bottom boot sectors (16,8,8,32) */
95
info->start[i++] = base + 0x00000000; /* - */
96
info->start[i++] = base + (0x00004000 << FLASH_SHIFT); /* +16k */
97
info->start[i++] = base + (0x00006000 << FLASH_SHIFT); /* +8k */
98
info->start[i++] = base + (0x00008000 << FLASH_SHIFT); /* +8k */
99
info->start[i++] = base + (0x00010000 << FLASH_SHIFT); /* +32k */
100
for (; i < info->sector_count; i++) /* +64k */
101
info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT)) - (0x00030000 << FLASH_SHIFT);
105
{ /* top boot sector types - not so useful */
106
/* set sector offsets for top boot block type */
107
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T)
108
{ /* AMDLV320T has 8 x 8k top boot sectors */
109
for (i = 0; i < info->sector_count - 8; i++) /* +64k */
110
info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT));
111
for (; i < info->sector_count; i++) /* +8k */
112
info->start[i] = base + (i * (0x00002000 << FLASH_SHIFT));
115
{ /* other types have 4 top boot sectors (32,8,8,16) */
116
for (i = 0; i < info->sector_count - 4; i++) /* +64k */
117
info->start[i] = base + (i * (0x00010000 << FLASH_SHIFT));
119
info->start[i++] = base + info->size - (0x00010000 << FLASH_SHIFT); /* -32k */
120
info->start[i++] = base + info->size - (0x00008000 << FLASH_SHIFT); /* -8k */
121
info->start[i++] = base + info->size - (0x00006000 << FLASH_SHIFT); /* -8k */
122
info->start[i] = base + info->size - (0x00004000 << FLASH_SHIFT); /* -16k */
127
/*-----------------------------------------------------------------------
129
void flash_print_info (flash_info_t *info)
133
if (info->flash_id == FLASH_UNKNOWN) {
134
printf ("missing or unknown FLASH type\n");
138
switch (info->flash_id & FLASH_VENDMASK) {
139
case FLASH_MAN_AMD: printf ("AMD "); break;
140
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
141
case FLASH_MAN_STM: printf ("ST "); break;
142
default: printf ("Unknown Vendor "); break;
145
switch (info->flash_id & FLASH_TYPEMASK) {
146
case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
148
case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
150
case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
152
case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n");
154
case FLASH_STMW320DB: printf ("M29W320B (32 Mbit, bottom boot sect)\n");
156
case FLASH_STMW320DT: printf ("M29W320T (32 Mbit, top boot sector)\n");
158
default: printf ("Unknown Chip Type\n");
162
printf (" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
164
printf (" Sector Start Addresses:");
165
for (i=0; i<info->sector_count; ++i) {
168
printf (" %08lX%s", info->start[i], info->protect[i] ? " (RO)" : " ");
174
* The following code cannot be run from FLASH!
177
#define AMD_ID_LV160T_MVS (AMD_ID_LV160T & FLASH_DATA_MASK)
178
#define AMD_ID_LV160B_MVS (AMD_ID_LV160B & FLASH_DATA_MASK)
179
#define AMD_ID_LV320T_MVS (AMD_ID_LV320T & FLASH_DATA_MASK)
180
#define AMD_ID_LV320B_MVS (AMD_ID_LV320B & FLASH_DATA_MASK)
181
#define STM_ID_W320DT_MVS (STM_ID_29W320DT & FLASH_DATA_MASK)
182
#define STM_ID_W320DB_MVS (STM_ID_29W320DB & FLASH_DATA_MASK)
183
#define AMD_MANUFACT_MVS (AMD_MANUFACT & FLASH_DATA_MASK)
184
#define FUJ_MANUFACT_MVS (FUJ_MANUFACT & FLASH_DATA_MASK)
185
#define STM_MANUFACT_MVS (STM_MANUFACT & FLASH_DATA_MASK)
187
#if (FLASH_BUS_WIDTH >= 16)
188
#define AUTOSELECT_ADDR1 0x0555
189
#define AUTOSELECT_ADDR2 0x02AA
190
#define AUTOSELECT_ADDR3 AUTOSELECT_ADDR1
192
#define AUTOSELECT_ADDR1 0x0AAA
193
#define AUTOSELECT_ADDR2 0x0555
194
#define AUTOSELECT_ADDR3 AUTOSELECT_ADDR1
197
#define AUTOSELECT_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
198
#define AUTOSELECT_DATA2 (0x00550055 & FLASH_DATA_MASK)
199
#define AUTOSELECT_DATA3 (0x00900090 & FLASH_DATA_MASK)
201
#define RESET_BANK_DATA (0x00F000F0 & FLASH_DATA_MASK)
204
static ulong flash_get_size (vu_long *address, flash_info_t *info)
208
FDT *addr = (FDT *)address;
210
ulong base = (ulong)address;
211
addr[AUTOSELECT_ADDR1] = AUTOSELECT_DATA1;
212
addr[AUTOSELECT_ADDR2] = AUTOSELECT_DATA2;
213
addr[AUTOSELECT_ADDR3] = AUTOSELECT_DATA3;
214
__asm__ __volatile__("sync");
218
value = addr[0]; /* manufacturer ID */
220
case AMD_MANUFACT_MVS:
221
info->flash_id = FLASH_MAN_AMD;
223
case FUJ_MANUFACT_MVS:
224
info->flash_id = FLASH_MAN_FUJ;
226
case STM_MANUFACT_MVS:
227
info->flash_id = FLASH_MAN_STM;
230
info->flash_id = FLASH_UNKNOWN;
231
info->sector_count = 0;
233
return (0); /* no or unknown flash */
235
#if (FLASH_BUS_WIDTH >= 16)
236
value = addr[1]; /* device ID */
238
value = addr[2]; /* device ID */
242
case AMD_ID_LV160T_MVS:
243
info->flash_id += FLASH_AM160T;
244
info->sector_count = 37;
245
info->size = (0x00200000 << FLASH_SHIFT);
246
break; /* => 2 or 4 MB */
248
case AMD_ID_LV160B_MVS:
249
info->flash_id += FLASH_AM160B;
250
info->sector_count = 37;
251
info->size = (0x00200000 << FLASH_SHIFT);
252
break; /* => 2 or 4 MB */
254
case AMD_ID_LV320T_MVS:
255
info->flash_id += FLASH_AM320T;
256
info->sector_count = 71;
257
info->size = (0x00400000 << FLASH_SHIFT);
258
break; /* => 4 or 8 MB */
260
case AMD_ID_LV320B_MVS:
261
info->flash_id += FLASH_AM320B;
262
info->sector_count = 71;
263
info->size = (0x00400000 << FLASH_SHIFT);
264
break; /* => 4 or 8MB */
266
case STM_ID_W320DT_MVS:
267
info->flash_id += FLASH_STMW320DT;
268
info->sector_count = 67;
269
info->size = (0x00400000 << FLASH_SHIFT);
270
break; /* => 4 or 8 MB */
272
case STM_ID_W320DB_MVS:
273
info->flash_id += FLASH_STMW320DB;
274
info->sector_count = 67;
275
info->size = (0x00400000 << FLASH_SHIFT);
276
break; /* => 4 or 8MB */
279
info->flash_id = FLASH_UNKNOWN;
280
return (0); /* => no or unknown flash */
284
/* set up sector start address table */
285
flash_get_offsets (base, info);
287
/* check for protected sectors */
288
for (i = 0; i < info->sector_count; i++) {
289
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
290
/* D0 = 1 if protected */
291
addr = (FDT *)(info->start[i]);
292
info->protect[i] = addr[2] & 1;
296
* Prevent writes to uninitialized FLASH.
298
if (info->flash_id != FLASH_UNKNOWN) {
299
addr = (FDT *)info->start[0];
300
*addr = RESET_BANK_DATA; /* reset bank */
306
/*-----------------------------------------------------------------------
309
#if (FLASH_BUS_WIDTH >= 16)
310
#define ERASE_ADDR1 0x0555
311
#define ERASE_ADDR2 0x02AA
313
#define ERASE_ADDR1 0x0AAA
314
#define ERASE_ADDR2 0x0555
317
#define ERASE_ADDR3 ERASE_ADDR1
318
#define ERASE_ADDR4 ERASE_ADDR1
319
#define ERASE_ADDR5 ERASE_ADDR2
321
#define ERASE_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
322
#define ERASE_DATA2 (0x00550055 & FLASH_DATA_MASK)
323
#define ERASE_DATA3 (0x00800080 & FLASH_DATA_MASK)
324
#define ERASE_DATA4 ERASE_DATA1
325
#define ERASE_DATA5 ERASE_DATA2
327
#define ERASE_SECTOR_DATA (0x00300030 & FLASH_DATA_MASK)
328
#define ERASE_CHIP_DATA (0x00100010 & FLASH_DATA_MASK)
329
#define ERASE_CONFIRM_DATA (0x00800080 & FLASH_DATA_MASK)
331
int flash_erase (flash_info_t *info, int s_first, int s_last)
333
FDT *addr = (FDT *)(info->start[0]);
335
int prot, sect, l_sect, flag;
336
ulong start, now, last;
338
__asm__ __volatile__ ("sync");
342
printf("\nflash_erase: first = %d @ 0x%08lx\n", s_first, info->start[s_first] );
343
printf(" last = %d @ 0x%08lx\n", s_last , info->start[s_last ] );
345
if ((s_first < 0) || (s_first > s_last)) {
346
if (info->flash_id == FLASH_UNKNOWN) {
347
printf ("- missing\n");
349
printf ("- no sectors to erase\n");
354
if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) {
355
printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id);
360
for (sect=s_first; sect<=s_last; ++sect) {
361
if (info->protect[sect]) {
367
printf ("- Warning: %d protected sectors will not be erased!\n",
375
/* Disable interrupts which might cause a timeout here */
376
flag = disable_interrupts();
378
addr[ERASE_ADDR1] = ERASE_DATA1;
379
addr[ERASE_ADDR2] = ERASE_DATA2;
380
addr[ERASE_ADDR3] = ERASE_DATA3;
381
addr[ERASE_ADDR4] = ERASE_DATA4;
382
addr[ERASE_ADDR5] = ERASE_DATA5;
384
for (sect = s_first; sect <= s_last; sect++) {
385
if (info->protect[sect] == 0) {
386
addr = (FDT *)(info->start[sect]);
387
addr[0] = ERASE_SECTOR_DATA;
396
* We wait for the last triggered sector
401
start = get_timer (0);
403
addr = (FDT *)(info->start[l_sect]);
405
while ((addr[0] & ERASE_CONFIRM_DATA) != ERASE_CONFIRM_DATA) {
406
if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
407
printf ("Timeout\n");
410
/* show that we're waiting */
411
if ((now - last) > 1000) { /* every second */
422
/*-----------------------------------------------------------------------
423
* Copy memory to flash, returns:
426
* 2 - Flash not erased
429
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
435
mvdebug (("+write_buff %p ==> 0x%08lx, count = 0x%08lx\n", src, addr, cnt));
437
wp = (addr & ~3); /* get lower word aligned address */
439
* handle unaligned start bytes
441
if ((l = addr - wp) != 0) {
442
mvdebug ((" handle unaligned start bytes (cnt = 0x%08lx)\n", cnt));
444
for (i=0, cp=wp; i<l; ++i, ++cp) {
445
data = (data << 8) | (*(uchar *)cp);
447
for (; i<BUFF_INC && cnt>0; ++i) {
448
data = (data << 8) | *src++;
452
for (; cnt==0 && i<BUFF_INC; ++i, ++cp) {
453
data = (data << 8) | (*(uchar *)cp);
456
if ((rc = write_word(info, wp, data)) != 0) {
463
* handle (half)word aligned part
465
mvdebug ((" handle word aligned part (cnt = 0x%08lx)\n", cnt));
466
while (cnt >= BUFF_INC) {
468
for (i=0; i<BUFF_INC; ++i) {
469
data = (data << 8) | *src++;
471
if ((rc = write_word(info, wp, data)) != 0) {
483
* handle unaligned tail bytes
485
mvdebug ((" handle unaligned tail bytes (cnt = 0x%08lx)\n", cnt));
487
for (i=0, cp=wp; i<BUFF_INC && cnt>0; ++i, ++cp) {
488
data = (data << 8) | *src++;
491
for (; i<BUFF_INC; ++i, ++cp) {
492
data = (data << 8) | (*(uchar *)cp);
495
return (write_word(info, wp, data));
498
#if (FLASH_BUS_WIDTH >= 16)
499
#define WRITE_ADDR1 0x0555
500
#define WRITE_ADDR2 0x02AA
502
#define WRITE_ADDR1 0x0AAA
503
#define WRITE_ADDR2 0x0555
504
#define WRITE_ADDR3 WRITE_ADDR1
507
#define WRITE_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
508
#define WRITE_DATA2 (0x00550055 & FLASH_DATA_MASK)
509
#define WRITE_DATA3 (0x00A000A0 & FLASH_DATA_MASK)
511
#define WRITE_CONFIRM_DATA ERASE_CONFIRM_DATA
513
/*-----------------------------------------------------------------------
514
* Write a byte to Flash, returns:
517
* 2 - Flash not erased
519
static int write_char (flash_info_t *info, ulong dest, uchar data)
521
vu_char *addr = (vu_char *)(info->start[0]);
525
/* Check if Flash is (sufficiently) erased */
526
if ((*((vu_char *)dest) & data) != data) {
527
printf(" *** ERROR: Flash not erased !\n");
530
flag = disable_interrupts();
532
addr[WRITE_ADDR1] = WRITE_DATA1;
533
addr[WRITE_ADDR2] = WRITE_DATA2;
534
addr[WRITE_ADDR3] = WRITE_DATA3;
535
*((vu_char *)dest) = data;
540
/* data polling for D7 */
541
start = get_timer (0);
542
addr = (vu_char *)dest;
543
while (( (*addr) & WRITE_CONFIRM_DATA) != (data & WRITE_CONFIRM_DATA)) {
544
if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
545
printf(" *** ERROR: Flash write timeout !");
549
mvdebug (("-write_byte\n"));
553
/*-----------------------------------------------------------------------
554
* Write a word to Flash, returns:
557
* 2 - Flash not erased
559
static int write_word (flash_info_t *info, ulong dest, ulong data)
564
mvdebug (("+write_word : 0x%08lx @ 0x%08lx\n", data, dest));
565
for ( i=0; (i < 4) && (result == 0); i++, dest+=1 )
566
result = write_char (info, dest, (data >> (8*(3-i))) & 0xff );
567
mvdebug (("-write_word\n"));
570
/*---------------------------------------------------------------- */