~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to board/gen860t/flash.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2001
 
3
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
4
 * Keith Outwater, keith_outwater@mvsi.com
 
5
 *
 
6
 * See file CREDITS for list of people who contributed to this
 
7
 * project.
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or
 
10
 * modify it under the terms of the GNU General Public License as
 
11
 * published by the Free Software Foundation; either version 2 of
 
12
 * the License, or (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 
22
 * MA 02111-1307 USA
 
23
 */
 
24
 
 
25
#include <common.h>
 
26
#include <mpc8xx.h>
 
27
 
 
28
#if defined(CONFIG_ENV_IS_IN_FLASH)
 
29
# ifndef  CONFIG_ENV_ADDR
 
30
#  define CONFIG_ENV_ADDR       (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
 
31
# endif
 
32
# ifndef  CONFIG_ENV_SIZE
 
33
#  define CONFIG_ENV_SIZE       CONFIG_ENV_SECT_SIZE
 
34
# endif
 
35
# ifndef  CONFIG_ENV_SECT_SIZE
 
36
#  define CONFIG_ENV_SECT_SIZE  CONFIG_ENV_SIZE
 
37
# endif
 
38
#endif
 
39
 
 
40
/*
 
41
 * Use buffered writes to flash by default - they are about 32x faster than
 
42
 * single byte writes.
 
43
 */
 
44
#ifndef  CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
 
45
#define CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
 
46
#endif
 
47
 
 
48
/*
 
49
 * Max time to wait (in mS) for flash device to allocate a write buffer.
 
50
 */
 
51
#ifndef CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT
 
52
#define CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT              100
 
53
#endif
 
54
 
 
55
/*
 
56
 * These functions support a single Intel StrataFlash device (28F128J3A)
 
57
 * in byte mode only!.  The flash routines are very basic and simple
 
58
 * since there isn't really any remapping necessary.
 
59
 */
 
60
 
 
61
/*
 
62
 * Intel SCS (Scalable Command Set) command definitions
 
63
 * (taken from 28F128J3A datasheet)
 
64
 */
 
65
#define SCS_READ_CMD                            0xff
 
66
#define SCS_READ_ID_CMD                         0x90
 
67
#define SCS_QUERY_CMD                           0x98
 
68
#define SCS_READ_STATUS_CMD                     0x70
 
69
#define SCS_CLEAR_STATUS_CMD            0x50
 
70
#define SCS_WRITE_BUF_CMD                       0xe8
 
71
#define SCS_PROGRAM_CMD                         0x40
 
72
#define SCS_BLOCK_ERASE_CMD                     0x20
 
73
#define SCS_BLOCK_ERASE_RESUME_CMD      0xd0
 
74
#define SCS_PROGRAM_RESUME_CMD          0xd0
 
75
#define SCS_BLOCK_ERASE_SUSPEND_CMD     0xb0
 
76
#define SCS_SET_BLOCK_LOCK_CMD          0x60
 
77
#define SCS_CLR_BLOCK_LOCK_CMD          0x60
 
78
 
 
79
/*
 
80
 * SCS status/extended status register bit definitions
 
81
 */
 
82
#define  SCS_SR7                                        0x80
 
83
#define  SCS_XSR7                                       0x80
 
84
 
 
85
/*---------------------------------------------------------------------*/
 
86
#if 0
 
87
#define DEBUG_FLASH
 
88
#endif
 
89
 
 
90
#ifdef DEBUG_FLASH
 
91
#define PRINTF(fmt,args...) printf(fmt ,##args)
 
92
#else
 
93
#define PRINTF(fmt,args...)
 
94
#endif
 
95
/*---------------------------------------------------------------------*/
 
96
 
 
97
flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
 
98
 
 
99
/*-----------------------------------------------------------------------
 
100
 * Functions
 
101
 */
 
102
static ulong flash_get_size (vu_char *addr, flash_info_t *info);
 
103
static int write_data8 (flash_info_t *info, ulong dest, uchar data);
 
104
static void flash_get_offsets (ulong base, flash_info_t *info);
 
105
 
 
106
/*-----------------------------------------------------------------------
 
107
 * Initialize the flash memory.
 
108
 */
 
109
unsigned long
 
110
flash_init (void)
 
111
{
 
112
        volatile immap_t     *immap  = (immap_t *)CONFIG_SYS_IMMR;
 
113
        volatile memctl8xx_t *memctl = &immap->im_memctl;
 
114
        unsigned long size_b0;
 
115
        int i;
 
116
 
 
117
        for (i= 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
 
118
                flash_info[i].flash_id = FLASH_UNKNOWN;
 
119
        }
 
120
 
 
121
        /*
 
122
         * The gen860t board only has one FLASH memory device, so the
 
123
         * FLASH Bank configuration is done statically.
 
124
         */
 
125
        PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM);
 
126
        size_b0 = flash_get_size((vu_char *)FLASH_BASE0_PRELIM, &flash_info[0]);
 
127
        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
 
128
                printf ("## Unknown FLASH on Bank 0: "
 
129
                                "ID 0x%lx, Size = 0x%08lx = %ld MB\n",
 
130
                                flash_info[0].flash_id,size_b0, size_b0 << 20);
 
131
        }
 
132
 
 
133
        PRINTF("## Before remap:\n"
 
134
                   "  BR0: 0x%08x    OR0: 0x%08x\n  BR1: 0x%08x    OR1: 0x%08x\n",
 
135
                   memctl->memc_br0, memctl->memc_or0,
 
136
                   memctl->memc_br1, memctl->memc_or1);
 
137
 
 
138
        /*
 
139
         * Remap FLASH according to real size
 
140
         */
 
141
        memctl->memc_or0 |= (-size_b0 & 0xFFFF8000);
 
142
        memctl->memc_br0 |= (CONFIG_SYS_FLASH_BASE & BR_BA_MSK);
 
143
 
 
144
        PRINTF("## After remap:\n"
 
145
                   "  BR0: 0x%08x    OR0: 0x%08x\n", memctl->memc_br0, memctl->memc_or0);
 
146
 
 
147
        /*
 
148
         * Re-do sizing to get full correct info
 
149
         */
 
150
        size_b0 = flash_get_size ((vu_char *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
 
151
        flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[0]);
 
152
        flash_info[0].size = size_b0;
 
153
 
 
154
#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
 
155
        /*
 
156
         * Monitor protection is ON by default
 
157
         */
 
158
        flash_protect(FLAG_PROTECT_SET,
 
159
                          CONFIG_SYS_MONITOR_BASE,
 
160
                          CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
 
161
                          &flash_info[0]);
 
162
#endif
 
163
 
 
164
#ifdef  CONFIG_ENV_IS_IN_FLASH
 
165
        /*
 
166
         * Environment protection ON by default
 
167
         */
 
168
        flash_protect(FLAG_PROTECT_SET,
 
169
                          CONFIG_ENV_ADDR,
 
170
                          CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
 
171
                          &flash_info[0]);
 
172
#endif
 
173
 
 
174
        PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0);
 
175
        return (size_b0);
 
176
}
 
177
 
 
178
 
 
179
/*-----------------------------------------------------------------------
 
180
 * Fill in the FLASH offset table
 
181
 */
 
182
static void
 
183
flash_get_offsets (ulong base, flash_info_t *info)
 
184
{
 
185
        int i;
 
186
 
 
187
        if (info->flash_id == FLASH_UNKNOWN) {
 
188
                return;
 
189
        }
 
190
 
 
191
        switch (info->flash_id & FLASH_VENDMASK) {
 
192
                case FLASH_MAN_INTEL:
 
193
                for (i = 0; i < info->sector_count; i++) {
 
194
                                info->start[i] = base;
 
195
                                base += 1024 * 128;
 
196
                }
 
197
                return;
 
198
 
 
199
                default:
 
200
                        printf ("Don't know sector offsets for FLASH"
 
201
                                " type 0x%lx\n", info->flash_id);
 
202
            return;
 
203
        }
 
204
}
 
205
 
 
206
 
 
207
/*-----------------------------------------------------------------------
 
208
 * Display FLASH device info
 
209
 */
 
210
void
 
211
flash_print_info (flash_info_t *info)
 
212
{
 
213
        int i;
 
214
 
 
215
        if (info->flash_id == FLASH_UNKNOWN) {
 
216
                printf ("Missing or unknown FLASH type\n");
 
217
                return;
 
218
        }
 
219
 
 
220
        switch (info->flash_id & FLASH_VENDMASK) {
 
221
        case FLASH_MAN_INTEL:
 
222
                        printf ("Intel ");
 
223
                        break;
 
224
        default:
 
225
                        printf ("Unknown Vendor ");
 
226
                        break;
 
227
        }
 
228
 
 
229
        switch (info->flash_id & FLASH_TYPEMASK) {
 
230
        case FLASH_28F128J3A:
 
231
                        printf ("28F128J3A (128Mbit = 128K x 128)\n");
 
232
                        break;
 
233
        default:
 
234
                        printf ("Unknown Chip Type\n");
 
235
                        break;
 
236
        }
 
237
 
 
238
        if (info->size >= (1024 * 1024)) {
 
239
                i = 20;
 
240
        } else {
 
241
                i = 10;
 
242
        }
 
243
        printf ("  Size: %ld %cB in %d Sectors\n",
 
244
                        info->size >> i,
 
245
                        (i == 20) ? 'M' : 'k',
 
246
                        info->sector_count);
 
247
 
 
248
        printf ("  Sector Start Addresses:");
 
249
        for (i=0; i<info->sector_count; ++i) {
 
250
                if ((i % 5) == 0)
 
251
                        printf ("\n   ");
 
252
                        printf (" %08lX%s",
 
253
                        info->start[i],
 
254
                        info->protect[i] ? " (RO)" : "     "
 
255
                );
 
256
        }
 
257
        printf ("\n");
 
258
        return;
 
259
}
 
260
 
 
261
 
 
262
/*-----------------------------------------------------------------------
 
263
 * Get size and other information for a FLASH device.
 
264
 * NOTE: The following code cannot be run from FLASH!
 
265
 */
 
266
static
 
267
ulong flash_get_size (vu_char *addr, flash_info_t *info)
 
268
{
 
269
#define NO_FLASH        0
 
270
 
 
271
        vu_char value[2];
 
272
 
 
273
        /*
 
274
         * Try to read the manufacturer ID
 
275
         */
 
276
        addr[0] = SCS_READ_CMD;
 
277
        addr[0] = SCS_READ_ID_CMD;
 
278
        value[0] = addr[0];
 
279
        value[1] = addr[2];
 
280
        addr[0] = SCS_READ_CMD;
 
281
 
 
282
        PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong)addr, value[0]);
 
283
        switch (value[0]) {
 
284
                case (INTEL_MANUFACT & 0xff):
 
285
                        info->flash_id = FLASH_MAN_INTEL;
 
286
                        break;
 
287
                default:
 
288
                        info->flash_id = FLASH_UNKNOWN;
 
289
                        info->sector_count = 0;
 
290
                        info->size = 0;
 
291
                        return (NO_FLASH);
 
292
        }
 
293
 
 
294
        /*
 
295
         * Read the device ID
 
296
         */
 
297
        PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong)(&addr[2]), value[1]);
 
298
        switch (value[1]) {
 
299
                case (INTEL_ID_28F128J3A & 0xff):
 
300
                        info->flash_id += FLASH_28F128J3A;
 
301
                        info->sector_count = 128;
 
302
                        info->size = 16 * 1024 * 1024;
 
303
                        break;
 
304
 
 
305
                default:
 
306
                        info->flash_id = FLASH_UNKNOWN;
 
307
                        return (NO_FLASH);
 
308
        }
 
309
 
 
310
        if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
 
311
                printf ("** ERROR: sector count %d > max (%d) **\n",
 
312
                                info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
 
313
                                info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
 
314
        }
 
315
        return (info->size);
 
316
}
 
317
 
 
318
 
 
319
/*-----------------------------------------------------------------------
 
320
 * Erase the specified sectors in the specified FLASH device
 
321
 */
 
322
int
 
323
flash_erase(flash_info_t *info, int s_first, int s_last)
 
324
{
 
325
        int flag, prot, sect;
 
326
        ulong start, now, last;
 
327
 
 
328
        if ((s_first < 0) || (s_first > s_last)) {
 
329
                if (info->flash_id == FLASH_UNKNOWN) {
 
330
                        printf ("- missing\n");
 
331
                } else {
 
332
                        printf ("- no sectors to erase\n");
 
333
                }
 
334
                return 1;
 
335
        }
 
336
 
 
337
        if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
 
338
                printf ("Can erase only Intel flash types - aborted\n");
 
339
                return 1;
 
340
        }
 
341
 
 
342
        prot = 0;
 
343
        for (sect=s_first; sect<=s_last; ++sect) {
 
344
                if (info->protect[sect]) {
 
345
                        prot++;
 
346
                }
 
347
        }
 
348
 
 
349
        if (prot) {
 
350
                printf ("- Warning: %d protected sectors will not be erased!\n",
 
351
                                prot);
 
352
        } else {
 
353
                printf ("\n");
 
354
        }
 
355
 
 
356
        start = get_timer (0);
 
357
        last  = start;
 
358
 
 
359
        /*
 
360
         * Start erase on unprotected sectors
 
361
         */
 
362
        for (sect = s_first; sect<=s_last; sect++) {
 
363
                if (info->protect[sect] == 0) { /* not protected */
 
364
                        vu_char *addr = (uchar *)(info->start[sect]);
 
365
                        vu_char status;
 
366
 
 
367
                        /*
 
368
                         * Disable interrupts which might cause a timeout
 
369
                         */
 
370
                        flag = disable_interrupts();
 
371
 
 
372
                        *addr = SCS_CLEAR_STATUS_CMD;
 
373
                        *addr = SCS_BLOCK_ERASE_CMD;
 
374
                        *addr = SCS_BLOCK_ERASE_RESUME_CMD;
 
375
 
 
376
                        /*
 
377
                         * Re-enable interrupts if necessary
 
378
                         */
 
379
                        if (flag)
 
380
                                enable_interrupts();
 
381
 
 
382
                        /*
 
383
                         * Wait at least 80us - let's wait 1 ms
 
384
                         */
 
385
                        udelay (1000);
 
386
 
 
387
                        while (((status = *addr) & SCS_SR7) != SCS_SR7) {
 
388
                                if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 
389
                                        printf ("Timeout\n");
 
390
                                        *addr = SCS_BLOCK_ERASE_SUSPEND_CMD;
 
391
                                        *addr = SCS_READ_CMD;
 
392
                                        return 1;
 
393
                                }
 
394
 
 
395
                                /*
 
396
                                 * Show that we're waiting
 
397
                                 */
 
398
                                if ((now - last) > 1000) {      /* 1 second */
 
399
                                        putc ('.');
 
400
                                        last = now;
 
401
                                }
 
402
                        }
 
403
                        *addr = SCS_READ_CMD;
 
404
                }
 
405
        }
 
406
        printf (" done\n");
 
407
        return 0;
 
408
}
 
409
 
 
410
 
 
411
#ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
 
412
/*
 
413
 * Allocate a flash buffer, fill it with data and write it to the flash.
 
414
 * 0 - OK
 
415
 * 1 - Timeout on buffer request
 
416
 *
 
417
 * NOTE: After the last call to this function, WSM status needs to be checked!
 
418
 */
 
419
static int
 
420
write_flash_buffer8(flash_info_t *info_p, vu_char *src_p, vu_char *dest_p,
 
421
                                    uint count)
 
422
{
 
423
        vu_char *block_addr_p = NULL;
 
424
        vu_char *start_addr_p = NULL;
 
425
        ulong blocksize = info_p->size / (ulong)info_p->sector_count;
 
426
 
 
427
        int i;
 
428
        uint time = get_timer(0);
 
429
 
 
430
        PRINTF("%s:%d: src: 0x%p dest: 0x%p  count: %d\n",
 
431
                   __FUNCTION__, __LINE__, src_p, dest_p, count);
 
432
 
 
433
        /*
 
434
         * What block are we in? We already know that the source address is
 
435
         * in the flash address range, but we also can't cross a block boundary.
 
436
         * We assume that the block does not cross a boundary (we'll check before
 
437
         * calling this function).
 
438
         */
 
439
        for (i = 0; i < info_p->sector_count; ++i) {
 
440
                if ( ((ulong)dest_p >= info_p->start[i]) &&
 
441
                    ((ulong)dest_p < (info_p->start[i] + blocksize)) ) {
 
442
                        PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
 
443
                                   __FUNCTION__, __LINE__, dest_p, i, info_p->start[i]);
 
444
                        block_addr_p = (vu_char *)info_p->start[i];
 
445
                        break;
 
446
                }
 
447
        }
 
448
 
 
449
        /*
 
450
         * Request a buffer
 
451
         */
 
452
        *block_addr_p = SCS_WRITE_BUF_CMD;
 
453
        while ((*block_addr_p & SCS_XSR7) != SCS_XSR7) {
 
454
                if (get_timer(time) >  CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT) {
 
455
                        PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
 
456
                                   __FUNCTION__, __LINE__, block_addr_p,
 
457
                                   CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT);
 
458
                        return 1;
 
459
                }
 
460
                *block_addr_p = SCS_WRITE_BUF_CMD;
 
461
        }
 
462
 
 
463
        /*
 
464
         * Fill the buffer with data
 
465
         */
 
466
        start_addr_p = dest_p;
 
467
        *block_addr_p = count - 1; /* flash device wants count - 1 */
 
468
        PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
 
469
                   __FUNCTION__, __LINE__, block_addr_p);
 
470
        for (i = 0; i < count; i++) {
 
471
                *start_addr_p++ = *src_p++;
 
472
        }
 
473
 
 
474
        /*
 
475
         * Flush buffer to flash
 
476
         */
 
477
        *block_addr_p = SCS_PROGRAM_RESUME_CMD;
 
478
#if 1
 
479
        time = get_timer(0);
 
480
        while ((*block_addr_p & SCS_SR7) != SCS_SR7) {
 
481
                if (get_timer(time) >  CONFIG_SYS_FLASH_WRITE_TOUT) {
 
482
                        PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
 
483
                                   __FUNCTION__, __LINE__, block_addr_p, CONFIG_SYS_FLASH_WRITE_TOUT);
 
484
                        return 1;
 
485
                }
 
486
        }
 
487
 
 
488
#endif
 
489
        return 0;
 
490
}
 
491
#endif
 
492
 
 
493
 
 
494
/*-----------------------------------------------------------------------
 
495
 * Copy memory to flash, returns:
 
496
 * 0 - OK
 
497
 * 1 - write timeout
 
498
 * 2 - Flash not erased
 
499
 * 4 - Flash not identified
 
500
 */
 
501
int
 
502
write_buff(flash_info_t *info_p, uchar *src_p, ulong addr, ulong count)
 
503
{
 
504
        int rc = 0;
 
505
#ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
 
506
#define FLASH_WRITE_BUF_SIZE    0x00000020      /* 32 bytes */
 
507
        int i;
 
508
        uint bufs;
 
509
        ulong buf_count;
 
510
        vu_char *sp;
 
511
        vu_char *dp;
 
512
#else
 
513
        ulong wp;
 
514
#endif
 
515
 
 
516
        PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
 
517
                   __FUNCTION__, __LINE__, (ulong)src_p, addr, (uint)count, count);
 
518
 
 
519
        if (info_p->flash_id == FLASH_UNKNOWN) {
 
520
                return 4;
 
521
        }
 
522
 
 
523
#ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
 
524
        sp = src_p;
 
525
        dp = (uchar *)addr;
 
526
 
 
527
        /*
 
528
         * For maximum performance, we want to align the start address to
 
529
         * the beginning of a write buffer boundary (i.e. A4-A0 of the
 
530
         * start address = 0). See how many bytes are required to get to a
 
531
         * write-buffer-aligned address.  If that number is non-zero, do
 
532
         * non buffered writes of the non-aligned data.  By doing non-buffered
 
533
         * writes, we avoid the problem of crossing a block (sector) boundary
 
534
         * with buffered writes.
 
535
         */
 
536
        buf_count = FLASH_WRITE_BUF_SIZE - (addr & (FLASH_WRITE_BUF_SIZE - 1));
 
537
        if (buf_count == FLASH_WRITE_BUF_SIZE) { /* already on a boundary */
 
538
                buf_count = 0;
 
539
        }
 
540
        if (buf_count > count) { /* not a full buffers worth of data to write */
 
541
                buf_count = count;
 
542
        }
 
543
        count -= buf_count;
 
544
 
 
545
        PRINTF("%s:%d: Write buffer alignment count = %ld\n",
 
546
                   __FUNCTION__, __LINE__, buf_count);
 
547
        while (buf_count-- >= 1) {
 
548
                if ((rc = write_data8(info_p, (ulong)dp++, *sp++)) != 0)  {
 
549
                        return (rc);
 
550
                }
 
551
        }
 
552
 
 
553
        PRINTF("%s:%d: count = %ld\n", __FUNCTION__, __LINE__, count);
 
554
        if (count == 0) { /* all done */
 
555
                PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
 
556
                           __FUNCTION__, __LINE__, FLASH_WRITE_BUF_SIZE);
 
557
                return (rc);
 
558
        }
 
559
 
 
560
        /*
 
561
         * Now that we are write buffer aligned, write full or partial buffers.
 
562
         * The fact that we are write buffer aligned automatically avoids
 
563
         * crossing a block address during a write buffer operation.
 
564
         */
 
565
        bufs = count / FLASH_WRITE_BUF_SIZE;
 
566
        PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__, __LINE__,
 
567
                   bufs, bufs);
 
568
        while (bufs >= 1) {
 
569
                rc = write_flash_buffer8(info_p, sp, dp, FLASH_WRITE_BUF_SIZE);
 
570
                if (rc != 0) {
 
571
                        PRINTF("%s:%d: ** Error writing buf %d\n",
 
572
                                   __FUNCTION__, __LINE__, bufs);
 
573
                        return (rc);
 
574
                }
 
575
                bufs--;
 
576
                sp += FLASH_WRITE_BUF_SIZE;
 
577
                dp += FLASH_WRITE_BUF_SIZE;
 
578
        }
 
579
 
 
580
        /*
 
581
         * Do the leftovers
 
582
         */
 
583
        i = count % FLASH_WRITE_BUF_SIZE;
 
584
        PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__, __LINE__, i, i);
 
585
        if (i > 0) {
 
586
                rc = write_flash_buffer8(info_p, sp, dp, i);
 
587
        }
 
588
 
 
589
        sp = (vu_char*)info_p->start[0];
 
590
        *sp = SCS_READ_CMD;
 
591
        return (rc);
 
592
 
 
593
#else
 
594
        wp = addr;
 
595
        while (count-- >= 1) {
 
596
                if((rc = write_data8(info_p, wp++, *src_p++)) != 0)
 
597
                        return (rc);
 
598
        }
 
599
        return 0;
 
600
#endif
 
601
}
 
602
 
 
603
 
 
604
/*-----------------------------------------------------------------------
 
605
 * Write a byte to Flash, returns:
 
606
 * 0 - OK
 
607
 * 1 - write timeout
 
608
 * 2 - Flash not erased
 
609
 */
 
610
static int
 
611
write_data8 (flash_info_t *info, ulong dest, uchar data)
 
612
{
 
613
        vu_char *addr = (vu_char *)dest;
 
614
        vu_char status;
 
615
        ulong start;
 
616
        int flag;
 
617
 
 
618
        /* Check if Flash is (sufficiently) erased */
 
619
        if ((*addr & data) != data) {
 
620
                return (2);
 
621
        }
 
622
        /* Disable interrupts which might cause a timeout here */
 
623
        flag = disable_interrupts();
 
624
 
 
625
        *addr = SCS_PROGRAM_CMD;
 
626
        *addr = data;
 
627
 
 
628
        /* re-enable interrupts if necessary */
 
629
        if (flag)
 
630
                enable_interrupts();
 
631
 
 
632
        start = get_timer (0);
 
633
 
 
634
        while (((status = *addr) & SCS_SR7) != SCS_SR7) {
 
635
                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 
636
                        *addr = SCS_READ_CMD;
 
637
                        return (1);
 
638
                }
 
639
        }
 
640
        *addr = SCS_READ_CMD;
 
641
        return (0);
 
642
}
 
643
 
 
644
/* vim: set ts=4 sw=4 tw=78: */