1 #ifndef CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL
2 #define CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL
3 //==========================================================================
7 // Intel 28Fxxx series flash driver
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 // Copyright (C) 2002 Gary Thomas
16 // eCos is free software; you can redistribute it and/or modify it under
17 // the terms of the GNU General Public License as published by the Free
18 // Software Foundation; either version 2 or (at your option) any later version.
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 // You should have received a copy of the GNU General Public License along
26 // with eCos; if not, write to the Free Software Foundation, Inc.,
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
29 // As a special exception, if other files instantiate templates or use macros
30 // or inline functions from this file, or you compile this file and link it
31 // with other works to produce a work based on this file, this file does not
32 // by itself cause the resulting work to be covered by the GNU General Public
33 // License. However the source code for this file must still be made available
34 // in accordance with section (3) of the GNU General Public License.
36 // This exception does not invalidate any other reasons why a work based on
37 // this file might be covered by the GNU General Public License.
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40 // at http://sources.redhat.com/ecos/ecos-license/
41 // -------------------------------------------
42 //####ECOSGPLCOPYRIGHTEND####
43 //==========================================================================
44 //#####DESCRIPTIONBEGIN####
47 // Contributors: jskov
52 // Notes: Device table could use unions of flags to save some space
54 //####DESCRIPTIONEND####
56 //==========================================================================
58 #include <pkgconf/hal.h>
59 #include <pkgconf/io_flash.h>
60 #include <pkgconf/devs_flash_intel_28fxxx.h>
62 #include <cyg/hal/hal_arch.h>
63 #include <cyg/hal/hal_cache.h>
64 #include CYGHWR_MEMORY_LAYOUT_H
66 #include <cyg/hal/hal_io.h>
68 #define _FLASH_PRIVATE_
69 #include <cyg/io/flash.h>
74 typedef void (*call_t)(char* str, ...);
75 extern void diag_printf(char* str, ...);
76 call_t d_print = &diag_printf;
84 //----------------------------------------------------------------------------
85 // Common device details.
86 #define FLASH_Read_ID FLASHWORD( 0x90 )
87 #define FLASH_Reset FLASHWORD( 0xFF )
88 #define FLASH_Program FLASHWORD( 0x40 )
89 #define FLASH_Write_Buffer FLASHWORD( 0xe8 )
90 #define FLASH_Block_Erase FLASHWORD( 0x20 )
91 #define FLASH_Confirm FLASHWORD( 0xD0 )
92 #define FLASH_Resume FLASHWORD( 0xD0 )
94 #define FLASH_Set_Lock FLASHWORD( 0x60 )
95 #define FLASH_Set_Lock_Confirm FLASHWORD( 0x01 )
96 #define FLASH_Clear_Lock FLASHWORD( 0x60 )
97 #define FLASH_Clear_Lock_Confirm FLASHWORD( 0xd0 )
98 #define FLASH_Lock_State_Mask FLASHWORD( 0x03 )
99 #define FLASH_Status_Locked FLASHWORD( 0x01 )
101 #define FLASH_Read_Status FLASHWORD( 0x70 )
102 #define FLASH_Clear_Status FLASHWORD( 0x50 )
103 #define FLASH_Status_Ready FLASHWORD( 0x80 )
105 // Status that we read back:
106 #define FLASH_ErrorMask FLASHWORD( 0x7E )
107 #define FLASH_ErrorProgram FLASHWORD( 0x10 )
108 #define FLASH_ErrorErase FLASHWORD( 0x20 )
109 #define FLASH_ErrorLock FLASHWORD( 0x30 )
110 #define FLASH_ErrorLowVoltage FLASHWORD( 0x08 )
111 #define FLASH_ErrorLocked FLASHWORD( 0x02 )
113 // Platform code must define the below
114 // #define CYGNUM_FLASH_INTERLEAVE : Number of interleaved devices (in parallel)
115 // #define CYGNUM_FLASH_SERIES : Number of devices in series
116 // #define CYGNUM_FLASH_WIDTH : Width of devices on platform
117 // #define CYGNUM_FLASH_BASE : Address of first device
119 #define CYGNUM_FLASH_BLANK (1)
120 #define CYGNUM_FLASH_DEVICES (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
124 # define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)))
126 #ifndef CYGHWR_FLASH_28FXXX_PLF_INIT
127 # define CYGHWR_FLASH_28FXXX_PLF_INIT()
129 #ifndef CYGHWR_FLASH_WRITE_ENABLE
130 #define CYGHWR_FLASH_WRITE_ENABLE()
132 #ifndef CYGHWR_FLASH_WRITE_DISABLE
133 #define CYGHWR_FLASH_WRITE_DISABLE()
136 //----------------------------------------------------------------------------
137 // Now that device properties are defined, include magic for defining
138 // accessor type and constants.
139 #include <cyg/io/flash_dev.h>
141 //----------------------------------------------------------------------------
142 // Information about supported devices
143 typedef struct flash_dev_info {
144 flash_data_t device_id;
145 cyg_uint32 block_size;
146 cyg_int32 block_count;
147 cyg_uint32 base_mask;
148 cyg_uint32 device_size;
149 cyg_bool locking; // supports locking
150 cyg_bool buffered_w; // supports buffered writes
152 cyg_uint32 bootblocks[12]; // 0 is bootblock offset, 1-11 sub-sector sizes (or 0)
154 cyg_uint32 banks[2]; // bank offets, highest to lowest (lowest should be 0)
155 // (only one entry for now, increase to support devices
159 static const flash_dev_info_t* flash_dev_info;
160 static const flash_dev_info_t supported_devices[] = {
161 #include <cyg/io/flash_28fxxx_parts.inl>
166 #define NUM_DEVICES (sizeof(supported_devices)/sizeof(flash_dev_info_t))
171 //----------------------------------------------------------------------------
172 // Functions that put the flash device into non-read mode must reside
176 void print_string(unsigned char *sp)
177 __attribute__ ((section (".2ram.print_string")));
179 void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
181 int flash_erase_block(void* block, unsigned int size)
182 __attribute__ ((section (".2ram.flash_erase_block")));
183 int flash_program_buf(void* addr, void* data, int len,
184 unsigned long block_mask, int buffer_size)
185 __attribute__ ((section (".2ram.flash_program_buf")));
186 int flash_lock_block(void* addr)
187 __attribute__ ((section (".2ram.flash_lock_block")));
188 int flash_unlock_block(void* block, int block_size, int blocks, void *)
189 __attribute__ ((section (".2ram.flash_unlock_block")));
194 //----------------------------------------------------------------------------
199 *((unsigned long *)0x40E0002C) = 0x04000000; // clear GPIO90
200 *((unsigned long *)0x40E00020) = 0x04000000; // set GPIO90
204 void print_string(unsigned char *sp) {
216 while((*cp) != 0x00) {
217 *((volatile unsigned long *)0x40E0002C) = 0x04000000; // clear GPIO90
218 *((volatile unsigned long *)0x40E00020) = 0x04000000; // set GPIO90
220 value = *((volatile unsigned long *)0x40100014); //FFLSR
223 while(!(value&0x40)){
224 value = *((volatile unsigned long *)0x40100014); //FFLSR
226 *((volatile unsigned long *)0x40E0002C) = 0x04000000; // clear GPIO90
227 *((volatile unsigned long *)0x40E00020) = 0x04000000; // set GPIO90
229 *((volatile unsigned long *)0x40100000) = (unsigned long)*cp; //FFTHR
231 *((volatile unsigned long *)0x40E0002C) = 0x04000000; // clear GPIO90
232 *((volatile unsigned long *)0x40E00020) = 0x04000000; // set GPIO90
236 *((volatile unsigned long *)0x40E0002C) = 0x04000000; // clear GPIO90
237 *((volatile unsigned long *)0x40E0002C) = 0x04000000; // clear GPIO90
238 *((volatile unsigned long *)0x40E0002C) = 0x04000000; // clear GPIO90
239 *((volatile unsigned long *)0x40E0002C) = 0x04000000; // clear GPIO90
240 *((volatile unsigned long *)0x40E00020) = 0x04000000; // set GPIO90
257 // Initialize driver details
264 CYGHWR_FLASH_28FXXX_PLF_INIT();
268 // Look through table for device data
269 flash_dev_info = supported_devices;
270 for (i = 0; i < NUM_DEVICES; i++) {
272 if (flash_dev_info->device_id == id[1])
277 // Did we find the device? If not, return error.
278 if (NUM_DEVICES == i){
279 return FLASH_ERR_DRV_WRONG_PART;
282 // Hard wired for now
283 flash_info.block_size = flash_dev_info->block_size;
284 flash_info.blocks = flash_dev_info->block_count * CYGNUM_FLASH_SERIES;
285 flash_info.start = (void *)CYGNUM_FLASH_BASE;
286 flash_info.end = (void *)(CYGNUM_FLASH_BASE + (flash_dev_info->device_size * CYGNUM_FLASH_SERIES));
291 //----------------------------------------------------------------------------
292 // Map a hardware status to a package error
294 flash_hwr_map_error(int e)
300 //----------------------------------------------------------------------------
301 // See if a range of FLASH addresses overlaps currently running code
303 flash_code_overlaps(void *start, void *end)
305 extern unsigned char _stext[], _etext[];
307 return ((((unsigned long)&_stext >= (unsigned long)start) &&
308 ((unsigned long)&_stext < (unsigned long)end)) ||
309 (((unsigned long)&_etext >= (unsigned long)start) &&
310 ((unsigned long)&_etext < (unsigned long)end)));
313 //----------------------------------------------------------------------------
316 // Only reads the manufacturer and part number codes for the first
317 // device(s) in series. It is assumed that any devices in series
318 // will be of the same type.
321 flash_query(void* data)
323 volatile flash_data_t *ROM;
324 flash_data_t* id = (flash_data_t*) data;
327 ROM = FLASH_P2V(CYGNUM_FLASH_BASE);
330 CYGHWR_FLASH_WRITE_ENABLE();
332 ROM[0] = FLASH_Read_ID;
334 // Manufacturers' code
339 ROM[0] = FLASH_Reset;
341 CYGHWR_FLASH_WRITE_DISABLE();
343 // Stall, waiting for flash to return to read mode.
347 //----------------------------------------------------------------------------
350 flash_erase_block(void* block, unsigned int block_size)
352 int res = FLASH_ERR_OK;
357 volatile flash_data_t *ROM;
358 volatile flash_data_t *b_p = (flash_data_t*) block;
359 volatile flash_data_t *b_v;
362 ROM = FLASH_P2V((unsigned long)block & flash_dev_info->base_mask);
364 // Is this the boot sector?
365 bootblock = (flash_dev_info->bootblock &&
366 (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
368 len = flash_dev_info->bootblocks[len_ix++];
370 len = flash_dev_info->block_size;
373 CYGHWR_FLASH_WRITE_ENABLE();
376 b_v = FLASH_P2V(b_p);
378 // Clear any error conditions
379 *b_v = FLASH_Clear_Status;
382 *b_v = FLASH_Block_Erase;
383 *b_v = FLASH_Confirm;
386 while(((stat = *b_v) & FLASH_Status_Ready) != FLASH_Status_Ready) {
387 if (--timeout == 0) break;
390 // Restore ROM to "normal" mode
396 if (stat & FLASH_ErrorMask) {
397 if (!(stat & FLASH_ErrorErase)) {
398 res = FLASH_ERR_HWR; // Unknown error
400 if (stat & FLASH_ErrorLowVoltage)
401 res = FLASH_ERR_LOW_VOLTAGE;
402 else if (stat & FLASH_ErrorLocked)
403 res = FLASH_ERR_PROTECT;
405 res = FLASH_ERR_ERASE;
409 // Check if block got erased
412 b_v = FLASH_P2V(b_p);
414 if (*b_v != FLASH_BlankValue ) {
415 // Only update return value if erase operation was OK
416 if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
423 len = flash_dev_info->bootblocks[len_ix++];
426 CYGHWR_FLASH_WRITE_DISABLE();
431 //----------------------------------------------------------------------------
434 flash_program_buf(void* addr, void* data, int len,
435 unsigned long block_mask, int buffer_size)
437 flash_data_t stat = 0;
439 volatile flash_data_t* ROM;
440 volatile flash_data_t* addr_v;
441 volatile flash_data_t* addr_p = (flash_data_t*) addr;
442 volatile flash_data_t* data_p = (flash_data_t*) data;
444 int res = FLASH_ERR_OK;
446 // Base address of device(s) being programmed.
447 ROM = FLASH_P2V((unsigned long)addr & flash_dev_info->base_mask);
449 CYGHWR_FLASH_WRITE_ENABLE();
451 // Clear any error conditions
452 ROM[0] = FLASH_Clear_Status;
455 addr_v = FLASH_P2V(addr_p);
457 *addr_v = FLASH_Program;
460 while(((stat = *addr_v) & FLASH_Status_Ready) != FLASH_Status_Ready) {
462 if (--timeout == 0) {
464 d_print("status is 0x%08X \n", stat);
466 res = FLASH_ERR_DRV_TIMEOUT;
470 if (stat & FLASH_ErrorMask) {
471 if (!(stat & FLASH_ErrorProgram))
472 res = FLASH_ERR_HWR; // Unknown error
474 if (stat & FLASH_ErrorLowVoltage)
475 res = FLASH_ERR_LOW_VOLTAGE;
476 else if (stat & FLASH_ErrorLocked)
477 res = FLASH_ERR_PROTECT;
479 res = FLASH_ERR_PROGRAM;
483 *addr_v = FLASH_Clear_Status;
484 *addr_v = FLASH_Reset;
485 if (*addr_v != *data_p++) {
486 res = FLASH_ERR_DRV_VERIFY;
489 len -= sizeof( flash_data_t );
492 // Restore ROM to "normal" mode
494 ROM[0] = FLASH_Reset;
496 CYGHWR_FLASH_WRITE_DISABLE();
498 // Ideally, we'd want to return not only the failure code, but also
499 // the address/device that reported the error.
508 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
509 //----------------------------------------------------------------------------
512 flash_lock_block(void* block)
514 volatile flash_data_t *ROM;
515 int res = FLASH_ERR_OK;
517 int timeout = 5000000;
518 volatile flash_data_t* b_p = (flash_data_t*) block;
519 volatile flash_data_t *b_v;
523 register unsigned long PC asm("pc");
525 unsigned char testbuffer[3];
531 *((volatile unsigned long *)0xa1000000) = PC;
532 *((volatile unsigned long *)0xa1000004) = testbuffer;
536 print_string(testbuffer);
543 print_string(testbuffer);
546 if (!flash_dev_info->locking) {
550 d_print("flash_lock_block %08x\n", block);
552 //ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask);
553 ROM = FLASH_P2V((unsigned long)block & flash_dev_info->base_mask);
555 // Is this the boot sector?
556 bootblock = (flash_dev_info->bootblock &&
557 (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
559 len = flash_dev_info->bootblocks[len_ix++];
561 len = flash_dev_info->block_size;
564 CYGHWR_FLASH_WRITE_ENABLE();
566 b_v = FLASH_P2V(b_p);
568 // Clear any error conditions
569 *b_v = FLASH_Clear_Status;
572 *b_v = FLASH_Set_Lock;
573 *b_v = FLASH_Set_Lock_Confirm; // Confirmation
574 *(b_v+2) = FLASH_Read_ID ;
575 while(((state = *(b_v+2)) & FLASH_Lock_State_Mask) != FLASH_Status_Locked) {
576 if (--timeout == 0) {
577 res = FLASH_ERR_DRV_TIMEOUT;
582 // Restore ROM to "normal" mode
586 b_p += len / sizeof( flash_data_t );
589 if (FLASH_ErrorLock == (state & FLASH_ErrorLock))
590 res = FLASH_ERR_LOCK;
592 if (res != FLASH_ERR_OK)
596 len = flash_dev_info->bootblocks[len_ix++];
599 CYGHWR_FLASH_WRITE_DISABLE();
603 //----------------------------------------------------------------------------
607 flash_unlock_block(void* block, int block_size, int blocks, void *myprint)
609 volatile flash_data_t *ROM;
610 int res = FLASH_ERR_OK;
612 int timeout = 5000000;
613 volatile flash_data_t* b_p = (flash_data_t*) block;
614 volatile flash_data_t *b_v;
617 //void (*func_ptr)(void) = myprint;
619 unsigned char testbuffer[16];
629 //*((unsigned long *)0xA0100000) = func_ptr;
630 //(*func_ptr)(testbuffer);
631 //(*func_ptr)("flash_unlock_block function entered now ....\n");
632 //return FLASH_ERR_OK;
634 d_print("flash_unlock_block function entered ....\n");
636 if (!flash_dev_info->locking) {
639 //ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask);
640 ROM = FLASH_P2V((unsigned long)block & flash_dev_info->base_mask);
642 d_print("flash_unlock_block dev %08x block %08x size %08x count %08x\n", ROM, block, block_size, blocks);
644 // Is this the boot sector?
645 bootblock = (flash_dev_info->bootblock &&
646 (flash_dev_info->bootblocks[0] == ((unsigned long)block - (unsigned long)ROM)));
648 len = flash_dev_info->bootblocks[len_ix++];
650 len = flash_dev_info->block_size;
653 CYGHWR_FLASH_WRITE_ENABLE();
656 b_v = FLASH_P2V(b_p);
657 // Clear any error conditions
658 *b_v = FLASH_Clear_Status;
661 *b_v = FLASH_Clear_Lock;
662 *b_v = FLASH_Clear_Lock_Confirm; // Confirmation
664 *(b_v+2) = FLASH_Read_ID;
666 while((state = *(b_v+2)) & FLASH_Lock_State_Mask) {
667 if (--timeout == 0) {
668 res = FLASH_ERR_DRV_TIMEOUT;
672 // Restore ROM to "normal" mode
676 b_p += len / sizeof( flash_data_t );
678 if (FLASH_ErrorLock == (state & FLASH_ErrorLock)) {
679 res = FLASH_ERR_LOCK;
681 if (res != FLASH_ERR_OK) {
685 len = flash_dev_info->bootblocks[len_ix++];
688 CYGHWR_FLASH_WRITE_DISABLE();
689 // (*func_ptr)("leaving flash_unlock_block function now\n");
693 // FIXME: Unlocking need to support some other parts in the future
694 // as well which take a little more diddling.
696 #endif // CYGHWR_IO_FLASH_BLOCK_LOCKING
697 #endif // CYGONCE_DEVS_FLASH_INTEL_28FXXX_INL