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

« back to all changes in this revision

Viewing changes to roms/u-boot/board/snmc/qs850/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 2003
 
3
 * MuLogic B.V.
 
4
 *
 
5
 * (C) Copyright 2001
 
6
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
7
 *
 
8
 * SPDX-License-Identifier:     GPL-2.0+
 
9
 */
 
10
 
 
11
#include <common.h>
 
12
#include <asm/ppc4xx.h>
 
13
#include <asm/u-boot.h>
 
14
#include <asm/processor.h>
 
15
 
 
16
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
 
17
 
 
18
 
 
19
#define FLASH_WORD_SIZE unsigned long
 
20
#define FLASH_ID_MASK 0xFFFFFFFF
 
21
 
 
22
/*-----------------------------------------------------------------------
 
23
 * Functions
 
24
 */
 
25
/* stolen from esteem192e/flash.c */
 
26
ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
 
27
 
 
28
static int write_word (flash_info_t *info, ulong dest, ulong data);
 
29
static void flash_get_offsets (ulong base, flash_info_t *info);
 
30
 
 
31
 
 
32
/*-----------------------------------------------------------------------
 
33
 */
 
34
 
 
35
unsigned long flash_init (void)
 
36
{
 
37
        unsigned long size_b0, size_b1;
 
38
        int i;
 
39
        uint pbcr;
 
40
        unsigned long base_b0, base_b1;
 
41
        volatile FLASH_WORD_SIZE* flash_base;
 
42
 
 
43
        /* Init: no FLASHes known */
 
44
        for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
 
45
                flash_info[i].flash_id = FLASH_UNKNOWN;
 
46
        }
 
47
 
 
48
        /* Static FLASH Bank configuration here */
 
49
        /* Test for 8M Flash first */
 
50
        debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_8M_PRELIM);
 
51
        flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_8M_PRELIM);
 
52
        size_b0 = flash_get_size(flash_base, &flash_info[0]);
 
53
 
 
54
        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
 
55
                printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
 
56
                size_b0, size_b0<<20);
 
57
                return 0;
 
58
        }
 
59
 
 
60
        if (size_b0 < 8*1024*1024) {
 
61
                /* Not quite 8M, try 4M Flash base address */
 
62
                debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_4M_PRELIM);
 
63
                flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_4M_PRELIM);
 
64
                size_b0 = flash_get_size(flash_base, &flash_info[0]);
 
65
        }
 
66
 
 
67
        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
 
68
                printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
 
69
                size_b0, size_b0<<20);
 
70
                return 0;
 
71
        }
 
72
 
 
73
        /* Only one bank */
 
74
        if (CONFIG_SYS_MAX_FLASH_BANKS == 1) {
 
75
                /* Setup offsets */
 
76
                flash_get_offsets ((ulong)flash_base, &flash_info[0]);
 
77
 
 
78
                /* Monitor protection ON by default */
 
79
                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
 
80
                        CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1, &flash_info[0]);
 
81
                size_b1 = 0 ;
 
82
                flash_info[0].size = size_b0;
 
83
                return(size_b0);
 
84
        }
 
85
 
 
86
        /* We have 2 banks */
 
87
        size_b1 = flash_get_size(flash_base, &flash_info[1]);
 
88
 
 
89
        /* Re-do sizing to get full correct info */
 
90
        if (size_b1) {
 
91
                mtdcr(EBC0_CFGADDR, PB0CR);
 
92
                pbcr = mfdcr(EBC0_CFGDATA);
 
93
                mtdcr(EBC0_CFGADDR, PB0CR);
 
94
                base_b1 = -size_b1;
 
95
                pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
 
96
                mtdcr(EBC0_CFGDATA, pbcr);
 
97
        }
 
98
 
 
99
        if (size_b0) {
 
100
                mtdcr(EBC0_CFGADDR, PB1CR);
 
101
                pbcr = mfdcr(EBC0_CFGDATA);
 
102
                mtdcr(EBC0_CFGADDR, PB1CR);
 
103
                base_b0 = base_b1 - size_b0;
 
104
                pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
 
105
                mtdcr(EBC0_CFGDATA, pbcr);
 
106
        }
 
107
 
 
108
        size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
 
109
        flash_get_offsets (base_b0, &flash_info[0]);
 
110
 
 
111
        /* monitor protection ON by default */
 
112
        (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
 
113
                CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1, &flash_info[0]);
 
114
 
 
115
        if (size_b1) {
 
116
                /* Re-do sizing to get full correct info */
 
117
                size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
 
118
                flash_get_offsets (base_b1, &flash_info[1]);
 
119
 
 
120
                /* monitor protection ON by default */
 
121
                (void)flash_protect(FLAG_PROTECT_SET, base_b1+size_b1-CONFIG_SYS_MONITOR_LEN,
 
122
                        base_b1+size_b1-1, &flash_info[1]);
 
123
 
 
124
                /* monitor protection OFF by default (one is enough) */
 
125
                (void)flash_protect(FLAG_PROTECT_CLEAR, base_b0+size_b0-CONFIG_SYS_MONITOR_LEN,
 
126
                        base_b0+size_b0-1, &flash_info[0]);
 
127
        } else {
 
128
                flash_info[1].flash_id = FLASH_UNKNOWN;
 
129
                flash_info[1].sector_count = -1;
 
130
        }
 
131
 
 
132
        flash_info[0].size = size_b0;
 
133
        flash_info[1].size = size_b1;
 
134
        return (size_b0 + size_b1);
 
135
}
 
136
 
 
137
 
 
138
/*-----------------------------------------------------------------------
 
139
 This code is specific to the AM29DL163/AM29DL232 for the QS850/QS823.
 
140
 */
 
141
 
 
142
static void flash_get_offsets (ulong base, flash_info_t *info)
 
143
{
 
144
        int i;
 
145
        long large_sect_size;
 
146
        long small_sect_size;
 
147
 
 
148
        /* set up sector start adress table */
 
149
        large_sect_size = info->size / (info->sector_count - 8 + 1);
 
150
        small_sect_size = large_sect_size / 8;
 
151
 
 
152
        if (info->flash_id & FLASH_BTYPE) {
 
153
 
 
154
                /* set sector offsets for bottom boot block type */
 
155
                for (i = 0; i < 7; i++) {
 
156
                        info->start[i] = base;
 
157
                        base += small_sect_size;
 
158
                }
 
159
 
 
160
                for (; i < info->sector_count; i++) {
 
161
                        info->start[i] = base;
 
162
                        base += large_sect_size;
 
163
                }
 
164
        }
 
165
        else
 
166
        {
 
167
                /* set sector offsets for top boot block type */
 
168
                for (i = 0; i < (info->sector_count - 8); i++) {
 
169
                        info->start[i] = base;
 
170
                        base += large_sect_size;
 
171
                }
 
172
 
 
173
                for (; i < info->sector_count; i++) {
 
174
                        info->start[i] = base;
 
175
                        base += small_sect_size;
 
176
                }
 
177
        }
 
178
}
 
179
 
 
180
/*-----------------------------------------------------------------------
 
181
 */
 
182
 
 
183
void flash_print_info  (flash_info_t *info)
 
184
{
 
185
        int i;
 
186
        uchar *boottype;
 
187
        uchar botboot[]=", bottom boot sect)\n";
 
188
        uchar topboot[]=", top boot sector)\n";
 
189
 
 
190
        if (info->flash_id == FLASH_UNKNOWN) {
 
191
                printf ("missing or unknown FLASH type\n");
 
192
                return;
 
193
        }
 
194
 
 
195
        switch (info->flash_id & FLASH_VENDMASK) {
 
196
                case FLASH_MAN_AMD:
 
197
                        printf ("AMD ");
 
198
                        break;
 
199
                case FLASH_MAN_FUJ:
 
200
                        printf ("FUJITSU ");
 
201
                        break;
 
202
                case FLASH_MAN_SST:
 
203
                        printf ("SST ");
 
204
                        break;
 
205
                case FLASH_MAN_STM:
 
206
                        printf ("STM ");
 
207
                        break;
 
208
                case FLASH_MAN_INTEL:
 
209
                        printf ("INTEL ");
 
210
                        break;
 
211
                default:
 
212
                        printf ("Unknown Vendor ");
 
213
                        break;
 
214
        }
 
215
 
 
216
        if (info->flash_id & 0x0001 ) {
 
217
                boottype = botboot;
 
218
        } else {
 
219
                boottype = topboot;
 
220
        }
 
221
 
 
222
        switch (info->flash_id & FLASH_TYPEMASK) {
 
223
                case FLASH_AM160B:
 
224
                        printf ("AM29LV160B (16 Mbit%s",boottype);
 
225
                        break;
 
226
                case FLASH_AM160T:
 
227
                        printf ("AM29LV160T (16 Mbit%s",boottype);
 
228
                        break;
 
229
                case FLASH_AMDL163T:
 
230
                        printf ("AM29DL163T (16 Mbit%s",boottype);
 
231
                        break;
 
232
                case FLASH_AMDL163B:
 
233
                        printf ("AM29DL163B (16 Mbit%s",boottype);
 
234
                        break;
 
235
                case FLASH_AM320B:
 
236
                        printf ("AM29LV320B (32 Mbit%s",boottype);
 
237
                        break;
 
238
                case FLASH_AM320T:
 
239
                        printf ("AM29LV320T (32 Mbit%s",boottype);
 
240
                        break;
 
241
                case FLASH_AMDL323T:
 
242
                        printf ("AM29DL323T (32 Mbit%s",boottype);
 
243
                        break;
 
244
                case FLASH_AMDL323B:
 
245
                        printf ("AM29DL323B (32 Mbit%s",boottype);
 
246
                        break;
 
247
                case FLASH_AMDL322T:
 
248
                        printf ("AM29DL322T (32 Mbit%s",boottype);
 
249
                        break;
 
250
                default:
 
251
                        printf ("Unknown Chip Type\n");
 
252
                        break;
 
253
        }
 
254
 
 
255
        printf ("  Size: %ld MB in %d Sectors\n",
 
256
        info->size >> 20, info->sector_count);
 
257
 
 
258
        printf ("  Sector Start Addresses:");
 
259
        for (i=0; i<info->sector_count; ++i) {
 
260
                if ((i % 5) == 0)
 
261
                        printf ("\n   ");
 
262
                printf (" %08lX%s", info->start[i],
 
263
                        info->protect[i] ? " (RO)" : "     ");
 
264
        }
 
265
        printf ("\n");
 
266
        return;
 
267
}
 
268
 
 
269
 
 
270
/*-----------------------------------------------------------------------
 
271
 * The following code cannot be run from FLASH!
 
272
 */
 
273
ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
 
274
{
 
275
        short i;
 
276
        ulong base = (ulong)addr;
 
277
        FLASH_WORD_SIZE value;
 
278
 
 
279
        /* Write auto select command: read Manufacturer ID */
 
280
 
 
281
        /*
 
282
         * Note: if it is an AMD flash and the word at addr[0000]
 
283
         * is 0x00890089 this routine will think it is an Intel
 
284
         * flash device and may(most likely) cause trouble.
 
285
         */
 
286
 
 
287
        addr[0x0000] = 0x00900090;
 
288
        if(addr[0x0000] != 0x00890089){
 
289
                addr[0x0555] = 0x00AA00AA;
 
290
                addr[0x02AA] = 0x00550055;
 
291
                addr[0x0555] = 0x00900090;
 
292
        }
 
293
        value = addr[0];
 
294
 
 
295
        switch (value) {
 
296
                case (AMD_MANUFACT & FLASH_ID_MASK):
 
297
                        info->flash_id = FLASH_MAN_AMD;
 
298
                        break;
 
299
                case (FUJ_MANUFACT & FLASH_ID_MASK):
 
300
                        info->flash_id = FLASH_MAN_FUJ;
 
301
                        break;
 
302
                case (STM_MANUFACT & FLASH_ID_MASK):
 
303
                        info->flash_id = FLASH_MAN_STM;
 
304
                        break;
 
305
                case (SST_MANUFACT & FLASH_ID_MASK):
 
306
                        info->flash_id = FLASH_MAN_SST;
 
307
                        break;
 
308
                case (INTEL_MANUFACT & FLASH_ID_MASK):
 
309
                        info->flash_id = FLASH_MAN_INTEL;
 
310
                        break;
 
311
                default:
 
312
                        info->flash_id = FLASH_UNKNOWN;
 
313
                        info->sector_count = 0;
 
314
                        info->size = 0;
 
315
                        return (0); /* no or unknown flash */
 
316
        }
 
317
 
 
318
        value = addr[1]; /* device ID */
 
319
 
 
320
        switch (value) {
 
321
                case (AMD_ID_LV160T & FLASH_ID_MASK):
 
322
                        info->flash_id += FLASH_AM160T;
 
323
                        info->sector_count = 35;
 
324
                        info->size = 0x00400000;
 
325
                        break; /* => 4 MB */
 
326
 
 
327
                case (AMD_ID_LV160B & FLASH_ID_MASK):
 
328
                        info->flash_id += FLASH_AM160B;
 
329
                        info->sector_count = 35;
 
330
                        info->size = 0x00400000;
 
331
                        break; /* => 4 MB */
 
332
 
 
333
                case (AMD_ID_DL163T & FLASH_ID_MASK):
 
334
                        info->flash_id += FLASH_AMDL163T;
 
335
                        info->sector_count = 39;
 
336
                        info->size = 0x00400000;
 
337
                        break; /* => 4 MB */
 
338
 
 
339
                case (AMD_ID_DL163B & FLASH_ID_MASK):
 
340
                        info->flash_id += FLASH_AMDL163B;
 
341
                        info->sector_count = 39;
 
342
                        info->size = 0x00400000;
 
343
                        break; /* => 4 MB */
 
344
 
 
345
                case (AMD_ID_DL323T & FLASH_ID_MASK):
 
346
                        info->flash_id += FLASH_AMDL323T;
 
347
                        info->sector_count = 71;
 
348
                        info->size = 0x00800000;
 
349
                        break; /* => 8 MB */
 
350
 
 
351
                case (AMD_ID_DL323B & FLASH_ID_MASK):
 
352
                        info->flash_id += FLASH_AMDL323B;
 
353
                        info->sector_count = 71;
 
354
                        info->size = 0x00800000;
 
355
                        break; /* => 8 MB */
 
356
 
 
357
                case (AMD_ID_DL322T & FLASH_ID_MASK):
 
358
                        info->flash_id += FLASH_AMDL322T;
 
359
                        info->sector_count = 71;
 
360
                        info->size = 0x00800000;
 
361
                        break; /* => 8 MB */
 
362
 
 
363
                default:
 
364
                        /* FIXME*/
 
365
                        info->flash_id = FLASH_UNKNOWN;
 
366
                        return (0); /* => no or unknown flash */
 
367
        }
 
368
 
 
369
        flash_get_offsets(base, info);
 
370
 
 
371
        /* check for protected sectors */
 
372
        for (i = 0; i < info->sector_count; i++) {
 
373
                /* read sector protection at sector address, (A7 .. A0) = 0x02 */
 
374
                /* D0 = 1 if protected */
 
375
                addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
 
376
                info->protect[i] = addr[2] & 1;
 
377
        }
 
378
 
 
379
        /*
 
380
         * Prevent writes to uninitialized FLASH.
 
381
         */
 
382
        if (info->flash_id != FLASH_UNKNOWN) {
 
383
                addr = (volatile FLASH_WORD_SIZE *)info->start[0];
 
384
                *addr = (0x00FF00FF & FLASH_ID_MASK);   /* reset bank */
 
385
        }
 
386
 
 
387
        return (info->size);
 
388
}
 
389
 
 
390
 
 
391
/*-----------------------------------------------------------------------
 
392
 */
 
393
 
 
394
int flash_erase (flash_info_t *info, int s_first, int s_last)
 
395
{
 
396
        volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
 
397
        int flag, prot, sect, l_sect;
 
398
        ulong start, now, last;
 
399
        int rcode = 0;
 
400
 
 
401
        if ((s_first < 0) || (s_first > s_last)) {
 
402
                if (info->flash_id == FLASH_UNKNOWN) {
 
403
                        printf ("- missing\n");
 
404
                } else {
 
405
                        printf ("- no sectors to erase\n");
 
406
                }
 
407
                return 1;
 
408
        }
 
409
 
 
410
        if ((info->flash_id == FLASH_UNKNOWN) ||
 
411
                (info->flash_id > FLASH_AMD_COMP) ) {
 
412
                printf ("Can't erase unknown flash type - aborted\n");
 
413
                return 1;
 
414
        }
 
415
 
 
416
        prot = 0;
 
417
        for (sect=s_first; sect<=s_last; ++sect) {
 
418
                if (info->protect[sect]) {
 
419
                        prot++;
 
420
                }
 
421
        }
 
422
 
 
423
        if (prot) {
 
424
                printf ("- Warning: %d protected sectors will not be erased!\n",
 
425
                        prot);
 
426
        } else {
 
427
                printf ("\n");
 
428
        }
 
429
 
 
430
        l_sect = -1;
 
431
 
 
432
        /* Disable interrupts which might cause a timeout here */
 
433
        flag = disable_interrupts();
 
434
        addr[0x0555] = 0x00AA00AA;
 
435
        addr[0x02AA] = 0x00550055;
 
436
        addr[0x0555] = 0x00800080;
 
437
        addr[0x0555] = 0x00AA00AA;
 
438
        addr[0x02AA] = 0x00550055;
 
439
        /* Start erase on unprotected sectors */
 
440
        for (sect = s_first; sect<=s_last; sect++) {
 
441
                if (info->protect[sect] == 0) { /* not protected */
 
442
                        addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
 
443
                        addr[0] = (0x00300030 & FLASH_ID_MASK);
 
444
                        l_sect = sect;
 
445
                }
 
446
        }
 
447
 
 
448
        /* re-enable interrupts if necessary */
 
449
        if (flag)
 
450
                enable_interrupts();
 
451
 
 
452
        /* wait at least 80us - let's wait 1 ms */
 
453
        udelay (1000);
 
454
 
 
455
        /*
 
456
         * We wait for the last triggered sector
 
457
         */
 
458
        if (l_sect < 0)
 
459
                goto DONE;
 
460
 
 
461
        start = get_timer (0);
 
462
        last  = start;
 
463
        addr = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
 
464
        while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
 
465
                        (0x00800080&FLASH_ID_MASK)  )
 
466
        {
 
467
                if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 
468
                        printf ("Timeout\n");
 
469
                        return 1;
 
470
                }
 
471
                /* show that we're waiting */
 
472
                if ((now - last) > 1000) { /* every second */
 
473
                        serial_putc ('.');
 
474
                        last = now;
 
475
                }
 
476
        }
 
477
 
 
478
DONE:
 
479
        /* reset to read mode */
 
480
        addr = (volatile FLASH_WORD_SIZE *)info->start[0];
 
481
        addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
 
482
 
 
483
        printf (" done\n");
 
484
        return rcode;
 
485
}
 
486
 
 
487
/*-----------------------------------------------------------------------
 
488
 * Copy memory to flash, returns:
 
489
 * 0 - OK
 
490
 * 1 - write timeout
 
491
 * 2 - Flash not erased
 
492
 */
 
493
 
 
494
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 
495
{
 
496
        ulong cp, wp, data;
 
497
        int l;
 
498
        int i, rc;
 
499
 
 
500
        wp = (addr & ~3); /* get lower word aligned address */
 
501
 
 
502
        /*
 
503
         * handle unaligned start bytes
 
504
         */
 
505
        if ((l = addr - wp) != 0) {
 
506
                data = 0;
 
507
                for (i=0, cp=wp; i<l; ++i, ++cp) {
 
508
                        data = (data << 8) | (*(uchar *)cp);
 
509
                }
 
510
                for (; i<4 && cnt>0; ++i) {
 
511
                        data = (data << 8) | *src++;
 
512
                        --cnt;
 
513
                        ++cp;
 
514
                }
 
515
                for (; cnt==0 && i<4; ++i, ++cp) {
 
516
                        data = (data << 8) | (*(uchar *)cp);
 
517
                }
 
518
 
 
519
                if ((rc = write_word(info, wp, data)) != 0) {
 
520
                        return (rc);
 
521
                }
 
522
                wp += 4;
 
523
        }
 
524
 
 
525
        /*
 
526
         * handle word aligned part
 
527
         */
 
528
        while (cnt >= 4) {
 
529
                data = 0;
 
530
                for (i=0; i<4; ++i) {
 
531
                        data = (data << 8) | *src++;
 
532
                }
 
533
                if ((rc = write_word(info, wp, data)) != 0) {
 
534
                        return (rc);
 
535
                }
 
536
                wp  += 4;
 
537
                cnt -= 4;
 
538
        }
 
539
 
 
540
        if (cnt == 0) {
 
541
                return (0);
 
542
        }
 
543
 
 
544
        /*
 
545
         * handle unaligned tail bytes
 
546
         */
 
547
        data = 0;
 
548
        for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
 
549
                data = (data << 8) | *src++;
 
550
                --cnt;
 
551
        }
 
552
        for (; i<4; ++i, ++cp) {
 
553
                data = (data << 8) | (*(uchar *)cp);
 
554
        }
 
555
 
 
556
        return (write_word(info, wp, data));
 
557
}
 
558
 
 
559
/*-----------------------------------------------------------------------
 
560
 * Write a word to Flash, returns:
 
561
 * 0 - OK
 
562
 * 1 - write timeout
 
563
 * 2 - Flash not erased
 
564
 */
 
565
static int write_word (flash_info_t *info, ulong dest, ulong data)
 
566
{
 
567
        vu_long *addr = (vu_long*)(info->start[0]);
 
568
        ulong start;
 
569
        int flag;
 
570
 
 
571
        /* Check if Flash is (sufficiently) erased */
 
572
        if ((*((vu_long *)dest) & data) != data) {
 
573
                return (2);
 
574
        }
 
575
 
 
576
        /* Disable interrupts which might cause a timeout here */
 
577
        flag = disable_interrupts();
 
578
 
 
579
        /* AMD stuff */
 
580
        addr[0x0555] = 0x00AA00AA;
 
581
        addr[0x02AA] = 0x00550055;
 
582
        addr[0x0555] = 0x00A000A0;
 
583
 
 
584
        *((vu_long *)dest) = data;
 
585
 
 
586
        /* re-enable interrupts if necessary */
 
587
        if (flag)
 
588
                enable_interrupts();
 
589
 
 
590
        /* data polling for D7 */
 
591
        start = get_timer(0);
 
592
 
 
593
        while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
 
594
                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 
595
                        return (1);
 
596
                }
 
597
        }
 
598
 
 
599
        return (0);
 
600
}