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

« back to all changes in this revision

Viewing changes to roms/u-boot/board/funkwerk/vovpn-gw/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 2004
 
3
 * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de)
 
4
 *
 
5
 * Support for the Elmeg VoVPN Gateway Module
 
6
 * ------------------------------------------
 
7
 * This is a signle bank flashdriver for INTEL 28F320J3, 28F640J3
 
8
 * and 28F128J3A flashs working in 8 Bit mode.
 
9
 *
 
10
 * Most of this code is taken from existing u-boot source code.
 
11
 *
 
12
 * SPDX-License-Identifier:     GPL-2.0+
 
13
 */
 
14
 
 
15
#include <common.h>
 
16
 
 
17
flash_info_t                            flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
 
18
 
 
19
#define FLASH_CMD_READ_ID               0x90
 
20
#define FLASH_CMD_READ_STATUS           0x70
 
21
#define FLASH_CMD_RESET                 0xff
 
22
#define FLASH_CMD_BLOCK_ERASE           0x20
 
23
#define FLASH_CMD_ERASE_CONFIRM         0xd0
 
24
#define FLASH_CMD_CLEAR_STATUS          0x50
 
25
#define FLASH_CMD_SUSPEND_ERASE         0xb0
 
26
#define FLASH_CMD_WRITE                 0x40
 
27
#define FLASH_CMD_WRITE_BUFF            0xe8
 
28
#define FLASH_CMD_PROG_RESUME           0xd0
 
29
#define FLASH_CMD_PROTECT               0x60
 
30
#define FLASH_CMD_PROTECT_SET           0x01
 
31
#define FLASH_CMD_PROTECT_CLEAR         0xd0
 
32
#define FLASH_STATUS_DONE               0x80
 
33
 
 
34
#define FLASH_WRITE_BUFFER_SIZE         32
 
35
 
 
36
#ifdef CONFIG_SYS_FLASH_16BIT
 
37
#define FLASH_WORD_SIZE                 unsigned short
 
38
#define FLASH_ID_MASK                   0xffff
 
39
#define FLASH_CMD_ADDR_SHIFT            0
 
40
#else
 
41
#define FLASH_WORD_SIZE                 unsigned char
 
42
#define FLASH_ID_MASK                   0xff
 
43
/* A0 is not used in either 8x or 16x for READ ID */
 
44
#define FLASH_CMD_ADDR_SHIFT            1
 
45
#endif
 
46
 
 
47
 
 
48
static unsigned long
 
49
flash_get(volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
 
50
{
 
51
        volatile FLASH_WORD_SIZE *p;
 
52
        FLASH_WORD_SIZE value;
 
53
        int i;
 
54
 
 
55
        addr[0] = FLASH_CMD_READ_ID;
 
56
 
 
57
        /* manufactor */
 
58
        value = addr[0 << FLASH_CMD_ADDR_SHIFT];
 
59
        switch (value) {
 
60
        case (INTEL_MANUFACT & FLASH_ID_MASK):
 
61
                info->flash_id = FLASH_MAN_INTEL;
 
62
                break;
 
63
        default:
 
64
                info->flash_id = FLASH_UNKNOWN;
 
65
                info->sector_count = 0;
 
66
                info->size = 0;
 
67
                *addr = FLASH_CMD_RESET;
 
68
                return (0);
 
69
 
 
70
        }
 
71
 
 
72
        /* device */
 
73
        value = addr[1 << FLASH_CMD_ADDR_SHIFT];
 
74
        switch (value) {
 
75
        case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
 
76
                info->flash_id += FLASH_28F320J3A;
 
77
                info->sector_count = 32;
 
78
                info->size = 0x00400000;
 
79
                break;
 
80
        case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
 
81
                info->flash_id += FLASH_28F640J3A;
 
82
                info->sector_count = 64;
 
83
                info->size = 0x00800000;
 
84
                break;
 
85
        case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
 
86
                info->flash_id += FLASH_28F128J3A;
 
87
                info->sector_count = 128;
 
88
                info->size = 0x01000000;
 
89
                break;
 
90
        default:
 
91
                info->flash_id = FLASH_UNKNOWN;
 
92
                info->sector_count = 0;
 
93
                info->size = 0;
 
94
                *addr = FLASH_CMD_RESET;
 
95
                return (0);
 
96
        }
 
97
 
 
98
        /* setup sectors */
 
99
        for (i = 0; i < info->sector_count; i++) {
 
100
                info->start[i] = (unsigned long)addr + (i * info->size/info->sector_count);
 
101
        }
 
102
 
 
103
        /* check protected sectors */
 
104
        for (i = 0; i < info->sector_count; i++) {
 
105
                p = (volatile FLASH_WORD_SIZE *)(info->start[i]);
 
106
                info->protect[i] = p[2 << FLASH_CMD_ADDR_SHIFT] & 1;
 
107
        }
 
108
 
 
109
        /* reset bank */
 
110
        *addr = FLASH_CMD_RESET;
 
111
        return (info->size);
 
112
}
 
113
 
 
114
unsigned long
 
115
flash_init(void)
 
116
{
 
117
        unsigned long   size;
 
118
        int             i;
 
119
 
 
120
        for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
 
121
                flash_info[i].flash_id = FLASH_UNKNOWN;
 
122
        }
 
123
        size = flash_get((volatile FLASH_WORD_SIZE *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
 
124
        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
 
125
                printf ("## Unknown FLASH Size=0x%08lx\n", size);
 
126
                return (0);
 
127
        }
 
128
 
 
129
        /* always protect 1 sector containing the HRCW */
 
130
        flash_protect(FLAG_PROTECT_SET,
 
131
                      flash_info[0].start[0],
 
132
                      flash_info[0].start[1] - 1,
 
133
                      &flash_info[0]);
 
134
 
 
135
#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
 
136
        flash_protect(FLAG_PROTECT_SET,
 
137
                      CONFIG_SYS_MONITOR_FLASH,
 
138
                      CONFIG_SYS_MONITOR_FLASH+CONFIG_SYS_MONITOR_LEN-1,
 
139
                      &flash_info[0]);
 
140
#endif
 
141
#ifdef  CONFIG_ENV_IS_IN_FLASH
 
142
        flash_protect(FLAG_PROTECT_SET,
 
143
                      CONFIG_ENV_ADDR,
 
144
                      CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
 
145
                      &flash_info[0]);
 
146
#endif
 
147
        return (size);
 
148
}
 
149
 
 
150
void
 
151
flash_print_info(flash_info_t *info)
 
152
{
 
153
        int i;
 
154
 
 
155
        if (info->flash_id == FLASH_UNKNOWN) {
 
156
                printf ("missing or unknown FLASH type\n");
 
157
                return;
 
158
        }
 
159
 
 
160
        switch (info->flash_id & FLASH_VENDMASK) {
 
161
        case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
 
162
        default:                printf ("Unknown Vendor ");     break;
 
163
        }
 
164
 
 
165
        switch (info->flash_id & FLASH_TYPEMASK) {
 
166
        case FLASH_28F320J3A:   printf ("28F320JA3 (32 Mbit)\n");
 
167
                                break;
 
168
        case FLASH_28F640J3A:   printf ("28F640JA3 (64 Mbit)\n");
 
169
                                break;
 
170
        case FLASH_28F128J3A:   printf ("28F128JA3 (128 Mbit)\n");
 
171
                                break;
 
172
        default:                printf ("Unknown Chip Type");
 
173
                                break;
 
174
        }
 
175
 
 
176
        printf ("  Size: %ld MB in %d Sectors\n",
 
177
                info->size >> 20, info->sector_count);
 
178
 
 
179
        printf ("  Sector Start Addresses:");
 
180
        for (i=0; i<info->sector_count; ++i) {
 
181
                if ((i % 5) == 0)
 
182
                        printf ("\n   ");
 
183
                printf (" %08lX%s",
 
184
                        info->start[i],
 
185
                        info->protect[i] ? " (RO)" : "     "
 
186
                );
 
187
        }
 
188
        printf ("\n");
 
189
}
 
190
 
 
191
int
 
192
flash_erase(flash_info_t *info, int s_first, int s_last)
 
193
{
 
194
        unsigned long start, now, last;
 
195
        int flag, prot, sect;
 
196
        volatile FLASH_WORD_SIZE *addr;
 
197
        FLASH_WORD_SIZE status;
 
198
 
 
199
        if ((s_first < 0) || (s_first > s_last)) {
 
200
                if (info->flash_id == FLASH_UNKNOWN) {
 
201
                        printf ("- missing\n");
 
202
                } else {
 
203
                        printf ("- no sectors to erase\n");
 
204
                }
 
205
                return (1);
 
206
        }
 
207
 
 
208
        if (info->flash_id == FLASH_UNKNOWN) {
 
209
                printf ("Cannot erase unknown flash - aborted\n");
 
210
                return (1);
 
211
        }
 
212
 
 
213
        prot = 0;
 
214
        for (sect=s_first; sect<=s_last; ++sect) {
 
215
                if (info->protect[sect]) {
 
216
                        prot++;
 
217
                }
 
218
        }
 
219
 
 
220
        if (prot) {
 
221
                printf ("- Warning: %d protected sectors will not be erased!\n", prot);
 
222
        } else {
 
223
                printf ("\n");
 
224
        }
 
225
 
 
226
        start = get_timer (0);
 
227
        last  = start;
 
228
 
 
229
        for (sect = s_first; sect<=s_last; sect++) {
 
230
                if (info->protect[sect]) {
 
231
                        continue;
 
232
                }
 
233
 
 
234
                addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
 
235
                /* Disable interrupts which might cause a timeout here */
 
236
                flag = disable_interrupts();
 
237
 
 
238
#ifdef DEBUG
 
239
                printf("Erase sector %d at start addr 0x%08X", sect, (unsigned int)info->start[sect]);
 
240
#endif
 
241
 
 
242
                *addr = FLASH_CMD_CLEAR_STATUS;
 
243
                *addr = FLASH_CMD_BLOCK_ERASE;
 
244
                *addr = FLASH_CMD_ERASE_CONFIRM;
 
245
 
 
246
                /* re-enable interrupts if necessary */
 
247
                if (flag) {
 
248
                        enable_interrupts();
 
249
                }
 
250
 
 
251
                /* wait at least 80us - let's wait 1 ms */
 
252
                udelay (1000);
 
253
 
 
254
                while (((status = *addr) & FLASH_STATUS_DONE) != FLASH_STATUS_DONE) {
 
255
                        if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 
256
                                printf("Flash erase timeout at address %lx\n", info->start[sect]);
 
257
                                *addr = FLASH_CMD_SUSPEND_ERASE;
 
258
                                *addr = FLASH_CMD_RESET;
 
259
                                return (1);
 
260
                        }
 
261
 
 
262
                        /* show that we're waiting */
 
263
                        if ((now - last) > 1000) {      /* every second */
 
264
                                putc ('.');
 
265
                                last = now;
 
266
                        }
 
267
                }
 
268
                *addr = FLASH_CMD_RESET;
 
269
        }
 
270
        printf (" done\n");
 
271
        return (0);
 
272
}
 
273
 
 
274
static int
 
275
write_buff2( volatile FLASH_WORD_SIZE *dst,
 
276
             volatile FLASH_WORD_SIZE *src,
 
277
             unsigned long cnt )
 
278
{
 
279
        unsigned long start;
 
280
        FLASH_WORD_SIZE status;
 
281
        int flag, i;
 
282
 
 
283
        start = get_timer (0);
 
284
        while (1) {
 
285
                /* Disable interrupts which might cause a timeout here */
 
286
                flag = disable_interrupts();
 
287
                dst[0] = FLASH_CMD_WRITE_BUFF;
 
288
                if ((status = *dst) & FLASH_STATUS_DONE) {
 
289
                        break;
 
290
                }
 
291
 
 
292
                /* re-enable interrupts if necessary */
 
293
                if (flag) {
 
294
                        enable_interrupts();
 
295
                }
 
296
 
 
297
                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 
298
                        return (-1);
 
299
                }
 
300
        }
 
301
        dst[0] = (FLASH_WORD_SIZE)(cnt - 1);
 
302
        for (i=0; i<cnt; i++) {
 
303
                dst[i] = src[i];
 
304
        }
 
305
        dst[0] = FLASH_CMD_PROG_RESUME;
 
306
 
 
307
        if (flag) {
 
308
                enable_interrupts();
 
309
        }
 
310
 
 
311
        return( 0 );
 
312
}
 
313
 
 
314
static int
 
315
poll_status( volatile FLASH_WORD_SIZE *addr )
 
316
{
 
317
        unsigned long start;
 
318
 
 
319
        start = get_timer (0);
 
320
        /* wait for error or finish */
 
321
        while (1) {
 
322
                if (*addr == FLASH_STATUS_DONE) {
 
323
                        if (*addr == FLASH_STATUS_DONE) {
 
324
                                break;
 
325
                        }
 
326
                }
 
327
                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 
328
                        *addr = FLASH_CMD_RESET;
 
329
                        return (-1);
 
330
                }
 
331
        }
 
332
        *addr = FLASH_CMD_RESET;
 
333
        return (0);
 
334
}
 
335
 
 
336
/*
 
337
 * write_buff return values:
 
338
 * 0 - OK
 
339
 * 1 - write timeout
 
340
 * 2 - Flash not erased
 
341
 * 4 - Flash not identified
 
342
 */
 
343
int
 
344
write_buff(flash_info_t *info, uchar *src, ulong udst, ulong cnt)
 
345
{
 
346
        volatile FLASH_WORD_SIZE *addr, *dst;
 
347
        unsigned long bcnt;
 
348
        int flag, i;
 
349
 
 
350
        if (info->flash_id == FLASH_UNKNOWN) {
 
351
                return (4);
 
352
        }
 
353
 
 
354
        addr = (volatile FLASH_WORD_SIZE *)(info->start[0]);
 
355
        dst = (volatile FLASH_WORD_SIZE *) udst;
 
356
 
 
357
#ifdef CONFIG_SYS_FLASH_16BIT
 
358
#error NYI
 
359
#else
 
360
        while (cnt > 0) {
 
361
                /* Check if buffer write is possible */
 
362
                if (cnt > 1 && (((unsigned long)dst & (FLASH_WRITE_BUFFER_SIZE - 1)) == 0)) {
 
363
                        bcnt = cnt > FLASH_WRITE_BUFFER_SIZE ? FLASH_WRITE_BUFFER_SIZE : cnt;
 
364
                        /* Check if Flash is (sufficiently) erased */
 
365
                        for (i=0; i<bcnt; i++) {
 
366
                                if ((dst[i] & src[i]) != src[i]) {
 
367
                                        return (2);
 
368
                                }
 
369
                        }
 
370
                        if (write_buff2( dst,src,bcnt ) != 0) {
 
371
                                addr[0] = FLASH_CMD_READ_STATUS;
 
372
                        }
 
373
                        if (poll_status( dst ) != 0) {
 
374
                                return (1);
 
375
                        }
 
376
                        cnt -= bcnt;
 
377
                        dst += bcnt;
 
378
                        src += bcnt;
 
379
                        continue;
 
380
                }
 
381
 
 
382
                /* Check if Flash is (sufficiently) erased */
 
383
                if ((*dst & *src) != *src) {
 
384
                        return (2);
 
385
                }
 
386
 
 
387
                /* Disable interrupts which might cause a timeout here */
 
388
                flag = disable_interrupts();
 
389
                addr[0] = FLASH_CMD_ERASE_CONFIRM;
 
390
                addr[0] = FLASH_CMD_WRITE;
 
391
                *dst++ = *src++;
 
392
                /* re-enable interrupts if necessary */
 
393
                if (flag) {
 
394
                        enable_interrupts();
 
395
                }
 
396
 
 
397
                if (poll_status( dst ) != 0) {
 
398
                        return (1);
 
399
                }
 
400
                cnt --;
 
401
        }
 
402
#endif
 
403
        return (0);
 
404
}
 
405
 
 
406
int
 
407
flash_real_protect(flash_info_t *info, long sector, int prot)
 
408
{
 
409
        volatile FLASH_WORD_SIZE *addr;
 
410
        unsigned long start;
 
411
 
 
412
        addr = (volatile FLASH_WORD_SIZE *)(info->start[sector]);
 
413
        *addr = FLASH_CMD_CLEAR_STATUS;
 
414
        *addr = FLASH_CMD_PROTECT;
 
415
 
 
416
        if(prot) {
 
417
                *addr = FLASH_CMD_PROTECT_SET;
 
418
        } else {
 
419
                *addr = FLASH_CMD_PROTECT_CLEAR;
 
420
        }
 
421
 
 
422
        /* wait for error or finish */
 
423
        start = get_timer (0);
 
424
        while(!(addr[0] & FLASH_STATUS_DONE)){
 
425
                if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 
426
                        printf("Flash protect timeout at address %lx\n",  info->start[sector]);
 
427
                        addr[0] = FLASH_CMD_RESET;
 
428
                        return (1);
 
429
                }
 
430
        }
 
431
 
 
432
        /* Set software protect flag */
 
433
        info->protect[sector] = prot;
 
434
        *addr = FLASH_CMD_RESET;
 
435
        return (0);
 
436
}