]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/flash/sst/39vfxxx/v2_0/include/flash_sst_39vfxxx.inl
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / flash / sst / 39vfxxx / v2_0 / include / flash_sst_39vfxxx.inl
1 #ifndef CYGONCE_DEVS_FLASH_SST_39VFXXX_INL
2 #define CYGONCE_DEVS_FLASH_SST_39VFXXX_INL
3 //==========================================================================
4 //
5 //      flash_sst_39vfxxx.inl
6 //
7 //      SST 39VFxxx series flash driver
8 //
9 //==========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14 //
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
18 //
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22 // for more details.
23 //
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 //
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
34 //
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
37 //
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //==========================================================================
43 //#####DESCRIPTIONBEGIN####
44 //
45 // Author(s):    gthomas
46 // Contributors: gthomas, jskov, rcassebohm
47 // Date:         2001-02-21
48 // Purpose:      
49 // Description:  
50 //              
51 // Notes:        FLASH_P2V is not properly used.
52 //               Needs locking.
53 //####DESCRIPTIONEND####
54 //
55 //==========================================================================
56
57 #include <pkgconf/hal.h>
58 #include <cyg/hal/hal_arch.h>
59 #include <cyg/hal/hal_cache.h>
60 #include CYGHWR_MEMORY_LAYOUT_H
61
62 #define  _FLASH_PRIVATE_
63 #include <cyg/io/flash.h>
64
65
66 //----------------------------------------------------------------------------
67 // Common device details.
68 #define FLASH_Read_ID                   FLASHWORD( 0x90 )
69 #define FLASH_Read_ID_Exit              FLASHWORD( 0xF0 )
70 #define FLASH_Reset                     FLASHWORD( 0xFF )
71 #define FLASH_Program                   FLASHWORD( 0xA0 )
72 #define FLASH_Block_Erase               FLASHWORD( 0x30 )
73
74 #define FLASH_Data                      FLASHWORD( 0x80 ) // Data complement
75 #define FLASH_Busy                      FLASHWORD( 0x40 ) // "Toggle" bit
76 #define FLASH_Err                       FLASHWORD( 0x20 )
77 #define FLASH_Sector_Erase_Timer        FLASHWORD( 0x08 )
78
79 #define FLASH_Setup_Addr1               (0x5555)
80 #define FLASH_Setup_Addr2               (0x2AAA)
81 #define FLASH_Setup_Code1               FLASHWORD( 0xAA )
82 #define FLASH_Setup_Code2               FLASHWORD( 0x55 )
83 #define FLASH_Setup_Erase               FLASHWORD( 0x80 )
84
85 // Platform code must define the below
86 // #define CYGNUM_FLASH_INTERLEAVE      : Number of interleaved devices (in parallel)
87 // #define CYGNUM_FLASH_SERIES          : Number of devices in series
88 // #define CYGNUM_FLASH_BASE            : Address of first device
89 // And select one of the below device variants
90
91 #ifdef CYGPKG_DEVS_FLASH_SST_39VF080
92 # define FLASH_BLOCK_SIZE               (0x1000*CYGNUM_FLASH_INTERLEAVE)
93 # define FLASH_NUM_REGIONS              (256)
94 # define CYGNUM_FLASH_BASE_MASK         (0xFFF00000u) // 1024kB devices
95 # define CYGNUM_FLASH_WIDTH             (8)
96 # define CYGNUM_FLASH_BLANK             (1)
97 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0xBF)
98 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0xD8)
99 #endif
100 #ifdef CYGPKG_DEVS_FLASH_SST_39VF016
101 # define FLASH_BLOCK_SIZE               (0x1000*CYGNUM_FLASH_INTERLEAVE)
102 # define FLASH_NUM_REGIONS              (512)
103 # define CYGNUM_FLASH_BASE_MASK         (0xFFE00000u) // 2048kB devices
104 # define CYGNUM_FLASH_WIDTH             (8)
105 # define CYGNUM_FLASH_BLANK             (1)
106 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0xBF)
107 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0xD9)
108 #endif
109 #ifdef CYGPKG_DEVS_FLASH_SST_39VF400
110 # define FLASH_BLOCK_SIZE               (0x1000*CYGNUM_FLASH_INTERLEAVE)
111 # define FLASH_NUM_REGIONS              (0x80000/FLASH_BLOCK_SIZE)
112 # define CYGNUM_FLASH_BASE_MASK         (0xFFF80000u) // 512kB devices
113 # define CYGNUM_FLASH_WIDTH             (16)
114 # define CYGNUM_FLASH_BLANK             (1)
115 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
116 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x2780)
117 #endif
118
119 #ifdef CYGPKG_DEVS_FLASH_SST_39VF160
120 # define FLASH_BLOCK_SIZE               ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
121 # define FLASH_NUM_REGIONS              ((2*1024*1024)/FLASH_BLOCK_SIZE)
122 # define CYGNUM_FLASH_BASE_MASK         (0xFFE00000u) // 2048kB devices
123 # define CYGNUM_FLASH_WIDTH             (16)
124 # define CYGNUM_FLASH_BLANK             (1)
125 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
126 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x2782)
127 #endif
128 #ifdef CYGPKG_DEVS_FLASH_SST_39VF1601
129 # define FLASH_BLOCK_SIZE               ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
130 # define FLASH_NUM_REGIONS              ((2*1024*1024)/FLASH_BLOCK_SIZE)
131 # define CYGNUM_FLASH_BASE_MASK         (0xFFE00000u) // 2048kB devices
132 # define CYGNUM_FLASH_WIDTH             (16)
133 # define CYGNUM_FLASH_BLANK             (1)
134 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
135 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x234B)
136 #endif
137 #ifdef CYGPKG_DEVS_FLASH_SST_39VF1602
138 # define FLASH_BLOCK_SIZE               ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
139 # define FLASH_NUM_REGIONS              ((2*1024*1024)/FLASH_BLOCK_SIZE)
140 # define CYGNUM_FLASH_BASE_MASK         (0xFFE00000u) // 2048kB devices
141 # define CYGNUM_FLASH_WIDTH             (16)
142 # define CYGNUM_FLASH_BLANK             (1)
143 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
144 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x234A)
145 #endif
146
147 #ifdef CYGPKG_DEVS_FLASH_SST_39VF320
148 # define FLASH_BLOCK_SIZE               ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
149 # define FLASH_NUM_REGIONS              ((4*1024*1024)/FLASH_BLOCK_SIZE)
150 # define CYGNUM_FLASH_BASE_MASK         (0xFFC00000u) // 4096kB devices
151 # define CYGNUM_FLASH_WIDTH             (16)
152 # define CYGNUM_FLASH_BLANK             (1)
153 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
154 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x2784)
155 #endif
156 #ifdef CYGPKG_DEVS_FLASH_SST_39VF3201
157 # define FLASH_BLOCK_SIZE               ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
158 # define FLASH_NUM_REGIONS              ((4*1024*1024)/FLASH_BLOCK_SIZE)
159 # define CYGNUM_FLASH_BASE_MASK         (0xFFC00000u) // 4096kB devices
160 # define CYGNUM_FLASH_WIDTH             (16)
161 # define CYGNUM_FLASH_BLANK             (1)
162 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
163 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x235B)
164 #endif
165 #ifdef CYGPKG_DEVS_FLASH_SST_39VF3202
166 # define FLASH_BLOCK_SIZE               ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
167 # define FLASH_NUM_REGIONS              ((4*1024*1024)/FLASH_BLOCK_SIZE)
168 # define CYGNUM_FLASH_BASE_MASK         (0xFFC00000u) // 4096kB devices
169 # define CYGNUM_FLASH_WIDTH             (16)
170 # define CYGNUM_FLASH_BLANK             (1)
171 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
172 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x235A)
173 #endif
174
175 #ifdef CYGPKG_DEVS_FLASH_SST_39VF6401
176 # define FLASH_BLOCK_SIZE               ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
177 # define FLASH_NUM_REGIONS              ((8*1024*1024)/FLASH_BLOCK_SIZE)
178 # define CYGNUM_FLASH_BASE_MASK         (0xFF800000u) // 8184kB devices
179 # define CYGNUM_FLASH_WIDTH             (16)
180 # define CYGNUM_FLASH_BLANK             (1)
181 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
182 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x236B)
183 #endif
184 #ifdef CYGPKG_DEVS_FLASH_SST_39VF6402
185 # define FLASH_BLOCK_SIZE               ((4*1024)*CYGNUM_FLASH_INTERLEAVE)
186 # define FLASH_NUM_REGIONS              ((8*1024*1024)/FLASH_BLOCK_SIZE)
187 # define CYGNUM_FLASH_BASE_MASK         (0xFF800000u) // 8184kB devices
188 # define CYGNUM_FLASH_WIDTH             (16)
189 # define CYGNUM_FLASH_BLANK             (1)
190 # define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x00BF)
191 # define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x236A)
192 #endif
193
194 #define FLASH_DEVICE_SIZE               (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS)
195 #define CYGNUM_FLASH_DEVICES            (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
196
197 //----------------------------------------------------------------------------
198 // Now that device properties are defined, include magic for defining
199 // accessor type and constants.
200 #include <cyg/io/flash_dev.h>
201
202 //----------------------------------------------------------------------------
203 // Functions that put the flash device into non-read mode must reside
204 // in RAM.
205 void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
206 int  flash_erase_block(void* block, unsigned int size) 
207     __attribute__ ((section (".2ram.flash_erase_block")));
208 int  flash_program_buf(void* addr, void* data, int len)
209     __attribute__ ((section (".2ram.flash_program_buf")));
210
211
212 //----------------------------------------------------------------------------
213 // Initialize driver details
214 int
215 flash_hwr_init(void)
216 {
217     flash_data_t id[2];
218
219     flash_dev_query(id);
220
221     // Check that flash_id data is matching the one the driver was
222     // configured for.
223     if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER
224         || id[1] != CYGNUM_FLASH_ID_DEVICE)
225         return FLASH_ERR_DRV_WRONG_PART;
226
227     // Hard wired for now
228     flash_info.block_size = FLASH_BLOCK_SIZE;
229     flash_info.blocks = FLASH_NUM_REGIONS;
230     flash_info.start = (void *)CYGNUM_FLASH_BASE;
231     flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_SERIES));
232     return FLASH_ERR_OK;
233 }
234
235 //----------------------------------------------------------------------------
236 // Map a hardware status to a package error
237 int
238 flash_hwr_map_error(int e)
239 {
240     return e;
241 }
242
243
244 //----------------------------------------------------------------------------
245 // See if a range of FLASH addresses overlaps currently running code
246 bool
247 flash_code_overlaps(void *start, void *end)
248 {
249     extern unsigned char _stext[], _etext[];
250
251     return ((((unsigned long)&_stext >= (unsigned long)start) &&
252              ((unsigned long)&_stext < (unsigned long)end)) ||
253             (((unsigned long)&_etext >= (unsigned long)start) &&
254              ((unsigned long)&_etext < (unsigned long)end)));
255 }
256
257 //----------------------------------------------------------------------------
258 // Flash Query
259 //
260 // Only reads the manufacturer and part number codes for the first
261 // device(s) in series. It is assumed that any devices in series
262 // will be of the same type.
263
264 void
265 flash_query(void* data)
266 {
267     volatile flash_data_t *ROM;
268     flash_data_t* id = (flash_data_t*) data;
269     int i;
270
271     ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
272
273     ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
274     ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
275     ROM[FLASH_Setup_Addr1] = FLASH_Read_ID;
276
277     // FIXME: 10ms delay
278     for (i = 10000; i > 0; i--);
279
280     // Manufacturers' code
281     id[0] = ROM[0];
282     // Part number
283     id[1] = ROM[1];
284
285     ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
286     ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
287     ROM[FLASH_Setup_Addr1] = FLASH_Read_ID_Exit;
288
289     // FIXME: 10ms delay
290     for (i = 10000; i > 0; i--);
291 }
292
293 //----------------------------------------------------------------------------
294 // Erase Block
295 int
296 flash_erase_block(void* block, unsigned int len)
297 {
298     volatile flash_data_t* ROM;
299     volatile flash_data_t* addr_ptr = (volatile flash_data_t*) block;
300
301     int res = FLASH_ERR_OK;
302
303     while ((FLASH_ERR_OK == res) && (len > 0)) {
304         int timeout;
305         flash_data_t state, prev_state;
306
307         // Base address of device(s) being programmed. 
308         ROM = (volatile flash_data_t*)((unsigned long)block & ~(FLASH_DEVICE_SIZE-1));
309
310         // Program data [byte] - 6 step sequence
311         ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
312         ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
313         ROM[FLASH_Setup_Addr1] = FLASH_Setup_Erase;
314         ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
315         ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
316         *addr_ptr = FLASH_Block_Erase;
317
318         // Wait for completion (bit 6 stops toggling)
319         timeout = 5000000;
320         prev_state = *addr_ptr & FLASH_Busy;
321         while (true) {
322             state = *addr_ptr & FLASH_Busy;
323             if (prev_state == state) {
324                 break;
325             }
326             if (--timeout == 0) {
327                 res = FLASH_ERR_DRV_TIMEOUT;
328                 break;
329             }
330             prev_state = state;
331         }
332
333         // Verify loaded data bytes
334         while (len > 0) {
335             if (*addr_ptr != FLASH_BlankValue) {
336                 // Only update return value if erase operation was OK
337                 if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
338                 break;
339             }
340             addr_ptr++;
341             len -= sizeof(*addr_ptr);
342         }
343     }
344
345     return FLASH_ERR_OK;
346 }
347
348 //----------------------------------------------------------------------------
349 // Program Buffer
350 int
351 flash_program_buf(void* addr, void* data, int len)
352 {
353     volatile flash_data_t* ROM;
354     volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
355     volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
356
357     int res = FLASH_ERR_OK;
358
359 #if 0
360     CYG_ASSERT((unsigned long)data_ptr & (sizeof(flash_data_t)-1) == 0, 
361                "Data not properly aligned");
362     CYG_ASSERT((unsigned long)addr_ptr & (CYGNUM_FLASH_INTERLEAVE*sizeof(flash_data_t)-1) == 0, 
363                "Addr not properly aligned (to first interleaved device)");
364 #endif
365
366     while ((FLASH_ERR_OK == res) && (len > 0)) {
367         int timeout;
368         flash_data_t state, prev_state;
369
370         // Base address of device(s) being programmed. 
371         ROM = (volatile flash_data_t*)((unsigned long)addr & ~(FLASH_DEVICE_SIZE-1));
372
373         // Program data [byte] - 4 step sequence
374         ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
375         ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
376         ROM[FLASH_Setup_Addr1] = FLASH_Program;
377         *addr_ptr = *data_ptr;
378
379         // Wait for completion (bit 6 stops toggling)
380         timeout = 5000000;
381         prev_state = *addr_ptr & FLASH_Busy;
382         while (true) {
383             state = *addr_ptr & FLASH_Busy;
384             if (prev_state == state) {
385                 break;
386             }
387             if (--timeout == 0) {
388                 res = FLASH_ERR_DRV_TIMEOUT;
389                 break;
390             }
391             prev_state = state;
392         }
393
394         // Verify loaded data bytes
395         if (*addr_ptr != *data_ptr) {
396             // Only update return value if program operation was OK
397             if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
398                 break;
399         }
400         addr_ptr++;
401         data_ptr++;
402         len -= sizeof(*data_ptr);
403     }
404
405
406     // Ideally, we'd want to return not only the failure code, but also
407     // the address/device that reported the error.
408     return res;
409 }
410
411 #endif // CYGONCE_DEVS_FLASH_SST_39VFXXX_INL