~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/mvblue/flash.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2000
 
3
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
4
 * (C) Copyright 2001-2003
 
5
 *
 
6
 * Changes for MATRIX Vision mvBLUE devices
 
7
 * MATRIX Vision GmbH / hg,as info@matrix-vision.de
 
8
 *
 
9
 * SPDX-License-Identifier:     GPL-2.0+
 
10
 */
 
11
 
 
12
#include <common.h>
 
13
#include <mpc824x.h>
 
14
 
 
15
#if 0
 
16
        #define mvdebug(p) printf ##p
 
17
#else
 
18
        #define mvdebug(p)
 
19
#endif
 
20
 
 
21
flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
 
22
 
 
23
#define FLASH_BUS_WIDTH         8
 
24
 
 
25
#if (FLASH_BUS_WIDTH==32)
 
26
        #define FLASH_DATA_MASK 0xffffffff
 
27
        #define FLASH_SHIFT 1
 
28
        #define FDT     vu_long
 
29
#elif (FLASH_BUS_WIDTH==16)
 
30
        #define FLASH_DATA_MASK 0xff
 
31
        #define FLASH_SHIFT 0
 
32
        #define FDT     vu_short
 
33
#elif (FLASH_BUS_WIDTH==8)
 
34
        #define FLASH_DATA_MASK 0xff
 
35
        #define FLASH_SHIFT 0
 
36
        #define FDT     vu_char
 
37
#else
 
38
        #error FLASH_BUS_WIDTH undefined
 
39
#endif
 
40
 
 
41
/*-----------------------------------------------------------------------
 
42
 * Functions
 
43
 */
 
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);
 
47
 
 
48
/*-----------------------------------------------------------------------
 
49
 */
 
50
unsigned long flash_init (void)
 
51
{
 
52
        unsigned long size_b0;
 
53
        int i;
 
54
 
 
55
        for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
 
56
                flash_info[i].flash_id = FLASH_UNKNOWN;
 
57
        }
 
58
 
 
59
        size_b0 = flash_get_size((vu_long *)0xffc00000, &flash_info[0]);
 
60
 
 
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);
 
64
        }
 
65
 
 
66
        flash_get_offsets (0xffc00000, &flash_info[0]);
 
67
        flash_info[0].size = size_b0;
 
68
 
 
69
        /* monitor protection OFF by default */
 
70
        flash_protect ( FLAG_PROTECT_CLEAR, 0xffc00000, 0x2000, flash_info );
 
71
 
 
72
        return size_b0;
 
73
}
 
74
 
 
75
/*-----------------------------------------------------------------------
 
76
 */
 
77
static void flash_get_offsets (ulong base, flash_info_t *info)
 
78
{
 
79
        int i;
 
80
 
 
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);
 
91
                }
 
92
                else
 
93
                {       /* other types have 4 bottom boot sectors (16,8,8,32) */
 
94
                        i = 0;
 
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);
 
102
                }
 
103
        }
 
104
        else
 
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));
 
113
                }
 
114
                else
 
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));
 
118
 
 
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         */
 
123
                }
 
124
        }
 
125
}
 
126
 
 
127
/*-----------------------------------------------------------------------
 
128
 */
 
129
void flash_print_info  (flash_info_t *info)
 
130
{
 
131
        int i;
 
132
 
 
133
        if (info->flash_id == FLASH_UNKNOWN) {
 
134
                printf ("missing or unknown FLASH type\n");
 
135
                return;
 
136
        }
 
137
 
 
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;
 
143
        }
 
144
 
 
145
        switch (info->flash_id & FLASH_TYPEMASK) {
 
146
        case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
 
147
                                break;
 
148
        case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
 
149
                                break;
 
150
        case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
 
151
                                break;
 
152
        case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
 
153
                                break;
 
154
        case FLASH_STMW320DB:   printf ("M29W320B (32 Mbit, bottom boot sect)\n");
 
155
                                break;
 
156
        case FLASH_STMW320DT:   printf ("M29W320T (32 Mbit, top boot sector)\n");
 
157
                                break;
 
158
        default:                printf ("Unknown Chip Type\n");
 
159
                                break;
 
160
        }
 
161
 
 
162
        printf ("  Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
 
163
 
 
164
        printf ("  Sector Start Addresses:");
 
165
        for (i=0; i<info->sector_count; ++i) {
 
166
                if ((i % 5) == 0)
 
167
                        printf ("\n   ");
 
168
                printf (" %08lX%s", info->start[i], info->protect[i] ? " (RO)" : "     ");
 
169
        }
 
170
        printf ("\n");
 
171
}
 
172
 
 
173
/*
 
174
 * The following code cannot be run from FLASH!
 
175
 */
 
176
 
 
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)
 
186
 
 
187
#if (FLASH_BUS_WIDTH >= 16)
 
188
        #define AUTOSELECT_ADDR1        0x0555
 
189
        #define AUTOSELECT_ADDR2        0x02AA
 
190
        #define AUTOSELECT_ADDR3        AUTOSELECT_ADDR1
 
191
#else
 
192
        #define AUTOSELECT_ADDR1        0x0AAA
 
193
        #define AUTOSELECT_ADDR2        0x0555
 
194
        #define AUTOSELECT_ADDR3        AUTOSELECT_ADDR1
 
195
#endif
 
196
 
 
197
#define AUTOSELECT_DATA1        (0x00AA00AA & FLASH_DATA_MASK)
 
198
#define AUTOSELECT_DATA2        (0x00550055 & FLASH_DATA_MASK)
 
199
#define AUTOSELECT_DATA3        (0x00900090 & FLASH_DATA_MASK)
 
200
 
 
201
#define RESET_BANK_DATA         (0x00F000F0 & FLASH_DATA_MASK)
 
202
 
 
203
 
 
204
static ulong flash_get_size (vu_long *address, flash_info_t *info)
 
205
{
 
206
        short i;
 
207
        FDT value;
 
208
        FDT *addr = (FDT *)address;
 
209
 
 
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");
 
215
 
 
216
        udelay(180);
 
217
 
 
218
        value = addr[0];                        /* manufacturer ID      */
 
219
        switch (value) {
 
220
        case AMD_MANUFACT_MVS:
 
221
                info->flash_id = FLASH_MAN_AMD;
 
222
                break;
 
223
        case FUJ_MANUFACT_MVS:
 
224
                info->flash_id = FLASH_MAN_FUJ;
 
225
                break;
 
226
        case STM_MANUFACT_MVS:
 
227
                info->flash_id = FLASH_MAN_STM;
 
228
                break;
 
229
        default:
 
230
                info->flash_id = FLASH_UNKNOWN;
 
231
                info->sector_count = 0;
 
232
                info->size = 0;
 
233
                return (0);                     /* no or unknown flash  */
 
234
        }
 
235
#if (FLASH_BUS_WIDTH >= 16)
 
236
        value = addr[1];                        /* device ID            */
 
237
#else
 
238
        value = addr[2];                        /* device ID            */
 
239
#endif
 
240
 
 
241
        switch (value) {
 
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         */
 
247
 
 
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         */
 
253
 
 
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         */
 
259
 
 
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          */
 
265
 
 
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         */
 
271
 
 
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          */
 
277
 
 
278
        default:
 
279
                info->flash_id = FLASH_UNKNOWN;
 
280
                return (0);                     /* => no or unknown flash */
 
281
 
 
282
        }
 
283
 
 
284
        /* set up sector start address table */
 
285
        flash_get_offsets (base, info);
 
286
 
 
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;
 
293
        }
 
294
 
 
295
        /*
 
296
         * Prevent writes to uninitialized FLASH.
 
297
         */
 
298
        if (info->flash_id != FLASH_UNKNOWN) {
 
299
                addr = (FDT *)info->start[0];
 
300
                *addr = RESET_BANK_DATA;        /* reset bank */
 
301
        }
 
302
        return (info->size);
 
303
}
 
304
 
 
305
 
 
306
/*-----------------------------------------------------------------------
 
307
 */
 
308
 
 
309
#if (FLASH_BUS_WIDTH >= 16)
 
310
        #define ERASE_ADDR1 0x0555
 
311
        #define ERASE_ADDR2 0x02AA
 
312
#else
 
313
        #define ERASE_ADDR1 0x0AAA
 
314
        #define ERASE_ADDR2 0x0555
 
315
#endif
 
316
 
 
317
#define ERASE_ADDR3 ERASE_ADDR1
 
318
#define ERASE_ADDR4 ERASE_ADDR1
 
319
#define ERASE_ADDR5 ERASE_ADDR2
 
320
 
 
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
 
326
 
 
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)
 
330
 
 
331
int     flash_erase (flash_info_t *info, int s_first, int s_last)
 
332
{
 
333
        FDT *addr = (FDT *)(info->start[0]);
 
334
 
 
335
        int prot, sect, l_sect, flag;
 
336
        ulong start, now, last;
 
337
 
 
338
        __asm__ __volatile__ ("sync");
 
339
        addr[0] = 0xf0;
 
340
        udelay(1000);
 
341
 
 
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 ] );
 
344
 
 
345
        if ((s_first < 0) || (s_first > s_last)) {
 
346
                if (info->flash_id == FLASH_UNKNOWN) {
 
347
                        printf ("- missing\n");
 
348
                } else {
 
349
                        printf ("- no sectors to erase\n");
 
350
                }
 
351
                return 1;
 
352
        }
 
353
 
 
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);
 
356
                return 1;
 
357
        }
 
358
 
 
359
        prot = 0;
 
360
        for (sect=s_first; sect<=s_last; ++sect) {
 
361
                if (info->protect[sect]) {
 
362
                        prot++;
 
363
                }
 
364
        }
 
365
 
 
366
        if (prot) {
 
367
                printf ("- Warning: %d protected sectors will not be erased!\n",
 
368
                        prot);
 
369
        } else {
 
370
                printf ("\n");
 
371
        }
 
372
 
 
373
        l_sect = -1;
 
374
 
 
375
        /* Disable interrupts which might cause a timeout here */
 
376
        flag = disable_interrupts();
 
377
 
 
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;
 
383
 
 
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;
 
388
                        l_sect = sect;
 
389
                }
 
390
        }
 
391
 
 
392
        if (flag)
 
393
                enable_interrupts();
 
394
 
 
395
        /*
 
396
         * We wait for the last triggered sector
 
397
         */
 
398
        if (l_sect < 0)
 
399
                goto DONE;
 
400
 
 
401
        start = get_timer (0);
 
402
        last  = start;
 
403
        addr = (FDT *)(info->start[l_sect]);
 
404
 
 
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");
 
408
                        return 1;
 
409
                }
 
410
                /* show that we're waiting */
 
411
                if ((now - last) > 1000) {      /* every second */
 
412
                        putc ('.');
 
413
                        last = now;
 
414
                }
 
415
        }
 
416
 
 
417
DONE:
 
418
        printf (" done\n");
 
419
        return 0;
 
420
}
 
421
 
 
422
/*-----------------------------------------------------------------------
 
423
 * Copy memory to flash, returns:
 
424
 * 0 - OK
 
425
 * 1 - write timeout
 
426
 * 2 - Flash not erased
 
427
 */
 
428
 
 
429
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 
430
{
 
431
#define BUFF_INC 4
 
432
        ulong cp, wp, data;
 
433
        int i, l, rc;
 
434
 
 
435
        mvdebug (("+write_buff %p ==> 0x%08lx, count = 0x%08lx\n", src, addr, cnt));
 
436
 
 
437
        wp = (addr & ~3);       /* get lower word aligned address */
 
438
        /*
 
439
         * handle unaligned start bytes
 
440
         */
 
441
        if ((l = addr - wp) != 0) {
 
442
                mvdebug ((" handle unaligned start bytes (cnt = 0x%08lx)\n", cnt));
 
443
                data = 0;
 
444
                for (i=0, cp=wp; i<l; ++i, ++cp) {
 
445
                        data = (data << 8) | (*(uchar *)cp);
 
446
                }
 
447
                for (; i<BUFF_INC && cnt>0; ++i) {
 
448
                        data = (data << 8) | *src++;
 
449
                        --cnt;
 
450
                        ++cp;
 
451
                }
 
452
                for (; cnt==0 && i<BUFF_INC; ++i, ++cp) {
 
453
                        data = (data << 8) | (*(uchar *)cp);
 
454
                }
 
455
 
 
456
                if ((rc = write_word(info, wp, data)) != 0) {
 
457
                        return (rc);
 
458
                }
 
459
                wp += BUFF_INC;
 
460
        }
 
461
 
 
462
        /*
 
463
         * handle (half)word aligned part
 
464
         */
 
465
        mvdebug ((" handle word aligned part (cnt = 0x%08lx)\n", cnt));
 
466
        while (cnt >= BUFF_INC) {
 
467
                data = 0;
 
468
                for (i=0; i<BUFF_INC; ++i) {
 
469
                        data = (data << 8) | *src++;
 
470
                }
 
471
                if ((rc = write_word(info, wp, data)) != 0) {
 
472
                        return (rc);
 
473
                }
 
474
                wp  += BUFF_INC;
 
475
                cnt -= BUFF_INC;
 
476
        }
 
477
 
 
478
        if (cnt == 0) {
 
479
                return (0);
 
480
        }
 
481
 
 
482
        /*
 
483
         * handle unaligned tail bytes
 
484
         */
 
485
        mvdebug ((" handle unaligned tail bytes (cnt = 0x%08lx)\n", cnt));
 
486
        data = 0;
 
487
        for (i=0, cp=wp; i<BUFF_INC && cnt>0; ++i, ++cp) {
 
488
                data = (data << 8) | *src++;
 
489
                --cnt;
 
490
        }
 
491
        for (; i<BUFF_INC; ++i, ++cp) {
 
492
                data = (data << 8) | (*(uchar *)cp);
 
493
        }
 
494
 
 
495
        return (write_word(info, wp, data));
 
496
}
 
497
 
 
498
#if (FLASH_BUS_WIDTH >= 16)
 
499
        #define WRITE_ADDR1 0x0555
 
500
        #define WRITE_ADDR2 0x02AA
 
501
#else
 
502
        #define WRITE_ADDR1 0x0AAA
 
503
        #define WRITE_ADDR2 0x0555
 
504
        #define WRITE_ADDR3 WRITE_ADDR1
 
505
#endif
 
506
 
 
507
#define WRITE_DATA1 (0x00AA00AA & FLASH_DATA_MASK)
 
508
#define WRITE_DATA2 (0x00550055 & FLASH_DATA_MASK)
 
509
#define WRITE_DATA3 (0x00A000A0 & FLASH_DATA_MASK)
 
510
 
 
511
#define WRITE_CONFIRM_DATA ERASE_CONFIRM_DATA
 
512
 
 
513
/*-----------------------------------------------------------------------
 
514
 * Write a byte to Flash, returns:
 
515
 * 0 - OK
 
516
 * 1 - write timeout
 
517
 * 2 - Flash not erased
 
518
 */
 
519
static int write_char (flash_info_t *info, ulong dest, uchar data)
 
520
{
 
521
        vu_char *addr = (vu_char *)(info->start[0]);
 
522
        ulong start;
 
523
        int flag;
 
524
 
 
525
        /* Check if Flash is (sufficiently) erased */
 
526
        if ((*((vu_char *)dest) & data) != data) {
 
527
                printf(" *** ERROR: Flash not erased !\n");
 
528
                return (2);
 
529
        }
 
530
        flag = disable_interrupts();
 
531
 
 
532
        addr[WRITE_ADDR1] = WRITE_DATA1;
 
533
        addr[WRITE_ADDR2] = WRITE_DATA2;
 
534
        addr[WRITE_ADDR3] = WRITE_DATA3;
 
535
        *((vu_char *)dest) = data;
 
536
 
 
537
        if (flag)
 
538
                enable_interrupts();
 
539
 
 
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 !");
 
546
                        return (1);
 
547
                }
 
548
        }
 
549
        mvdebug (("-write_byte\n"));
 
550
        return (0);
 
551
}
 
552
 
 
553
/*-----------------------------------------------------------------------
 
554
 * Write a word to Flash, returns:
 
555
 * 0 - OK
 
556
 * 1 - write timeout
 
557
 * 2 - Flash not erased
 
558
 */
 
559
static int write_word (flash_info_t *info, ulong dest, ulong data)
 
560
{
 
561
        int i,
 
562
                result = 0;
 
563
 
 
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"));
 
568
        return result;
 
569
}
 
570
/*---------------------------------------------------------------- */