1 /************************************************************************/
3 /* AMD CFI Enabled Flash Memory Drivers */
4 /* File name: CFIFLASH.C */
5 /* Revision: 1.0 5/07/98 */
7 /* Copyright (c) 1998 ADVANCED MICRO DEVICES, INC. All Rights Reserved. */
8 /* This software is unpublished and contains the trade secrets and */
9 /* confidential proprietary information of AMD. Unless otherwise */
10 /* provided in the Software Agreement associated herewith, it is */
11 /* licensed in confidence "AS IS" and is not to be reproduced in whole */
12 /* or part by any means except for backup. Use, duplication, or */
13 /* disclosure by the Government is subject to the restrictions in */
14 /* paragraph (b) (3) (B) of the Rights in Technical Data and Computer */
15 /* Software clause in DFAR 52.227-7013 (a) (Oct 1988). */
16 /* Software owned by */
17 /* Advanced Micro Devices, Inc., */
20 /* Sunnyvale, CA 94088-3453. */
21 /************************************************************************/
22 /* This software constitutes a basic shell of source code for */
23 /* programming all AMD Flash components. AMD */
24 /* will not be responsible for misuse or illegal use of this */
25 /* software for devices not supported herein. AMD is providing */
26 /* this source code "AS IS" and will not be responsible for */
27 /* issues arising from incorrect user implementation of the */
28 /* source code herein. It is the user's responsibility to */
29 /* properly design-in this source code. */
31 /************************************************************************/
35 #include "lib_types.h"
36 #include "lib_printf.h"
37 #include "lib_string.h"
38 #include "cfe_timer.h"
40 #define CFI_USLEEP(x) cfe_usleep(x)
43 #include <linux/param.h>
44 #include <linux/sched.h>
45 #include <linux/timer.h>
46 #include <asm/delay.h>
47 #include <bcm_map_part.h>
48 #define CFI_USLEEP(x) udelay(x)
53 #include "flash_api.h"
60 #define MAXSECTORS 1024 /* maximum number of sectors supported */
62 /* Standard Boolean declarations */
66 /* Define different type of flash */
67 #define FLASH_UNDEFINED 0
72 /* Command codes for the flash_command routine */
73 #define FLASH_RESET 0 /* reset to read mode */
74 #define FLASH_READ_ID 1 /* read device ID */
75 #define FLASH_CFIQUERY 2 /* CFI query */
76 #define FLASH_UB 3 /* go into unlock bypass mode */
77 #define FLASH_PROG 4 /* program a unsigned short */
78 #define FLASH_UBRESET 5 /* reset to read mode from unlock bypass mode */
79 #define FLASH_SERASE 6 /* sector erase */
81 /* Return codes from flash_status */
82 #define STATUS_READY 0 /* ready for action */
83 #define STATUS_TIMEOUT 1 /* operation timed out */
85 /* A list of AMD compatible device ID's - add others as needed */
86 #define ID_AM29DL800T 0x224A
87 #define ID_AM29DL800B 0x22CB
88 #define ID_AM29LV800T 0x22DA
89 #define ID_AM29LV800B 0x225B
90 #define ID_AM29LV400B 0x22BA
91 #define ID_AM29LV200BT 0x223B
93 #define ID_AM29LV160B 0x2249
94 #define ID_AM29LV160T 0x22C4
96 #define ID_AM29LV320T 0x22F6
97 #define ID_MX29LV320AT 0x22A7
98 #define ID_AM29LV320B 0x22F9
99 #define ID_MX29LV320AB 0x22A8
100 #define ID_MX29LV640BT 0x22C9
102 #define ID_AM29LV320M 0x227E
103 #define ID_AM29LV320MB 0x2200
104 #define ID_AM29LV320MT 0x2201
106 #define ID_SST39VF200A 0x2789
107 #define ID_SST39VF400A 0x2780
108 #define ID_SST39VF800A 0x2781
109 #define ID_SST39VF1601 0x234B
110 #define ID_SST39VF3201 0x235B
111 // add SST and ST flash device id
112 #define ID_SST39VF3202 0x235A
113 #define ID_M29W320ET 0x2256
114 #define ID_SST39VF6401 0x236B
115 /* A list of Intel compatible device ID's - add others as needed */
116 #define ID_I28F160C3T 0x88C2
117 #define ID_I28F160C3B 0x88C3
118 #define ID_I28F320C3T 0x88C4
119 #define ID_I28F320C3B 0x88C5
120 #define ID_I28F640J3 0x0017
122 #define CFI_FLASH_DEVICES \
123 {{ID_AM29DL800T, "AM29DL800T"}, \
124 {ID_AM29DL800B, "AM29DL800B"}, \
125 {ID_AM29LV800T, "AM29LV800T"}, \
126 {ID_AM29LV800B, "AM29LV800B"}, \
127 {ID_AM29LV400B, "AM29LV400B"}, \
128 {ID_AM29LV200BT, "AM29LV200BT"}, \
129 {ID_AM29LV160B, "AM29LV160B"}, \
130 {ID_AM29LV160T, "AM29LV160T"}, \
131 {ID_AM29LV320T, "AM29LV320T"}, \
132 {ID_MX29LV320AT, "MX29LV320AT"}, \
133 {ID_AM29LV320B, "AM29LV320B"}, \
134 {ID_MX29LV320AB, "MX29LV320AB"}, \
135 {ID_AM29LV320M, "AM29LV320M"}, \
136 {ID_AM29LV320MB, "AM29LV320MB"}, \
137 {ID_AM29LV320MT, "AM29LV320MT"}, \
138 {ID_MX29LV640BT, "MX29LV640BT"}, \
139 {ID_SST39VF200A, "SST39VF200A"}, \
140 {ID_SST39VF400A, "SST39VF400A"}, \
141 {ID_SST39VF800A, "SST39VF800A"}, \
142 {ID_SST39VF1601, "SST39VF1601"}, \
143 {ID_SST39VF3201, "SST39VF3201"}, \
144 {ID_SST39VF3202, "SST39VF3202"}, \
145 {ID_M29W320ET, "M29W320ET"}, \
146 {ID_SST39VF6401, "SST39VF6401"}, \
147 {ID_I28F160C3T, "I28F160C3T"}, \
148 {ID_I28F160C3B, "I28F160C3B"}, \
149 {ID_I28F320C3T, "I28F320C3T"}, \
150 {ID_I28F320C3B, "I28F320C3B"}, \
151 {ID_I28F640J3, "I28F640J3"}, \
156 /* A structure for identifying a flash part. There is one for each
157 * of the flash part definitions. We need to keep track of the
158 * sector organization, the address register used, and the size
162 char *name; /* "Am29DL800T", etc. */
163 unsigned long addr; /* physical address, once translated */
164 int areg; /* Can be set to zero for all parts */
165 int nsect; /* # of sectors -- 19 in LV, 22 in DL */
166 int bank1start; /* first sector # in bank 1 */
167 int bank2start; /* first sector # in bank 2, if DL part */
169 long size; /* # of bytes in this sector */
170 long base; /* offset from beginning of device */
171 int bank; /* 1 or 2 for DL; 1 for LV */
172 } sec[MAXSECTORS]; /* per-sector info */
176 * This structure holds all CFI query information as defined
177 * in the JEDEC standard. All information up to
178 * primary_extended_query is standard among all manufactures
179 * with CFI enabled devices.
183 int num_erase_blocks; /* Number of sector defs. */
184 long device_size; /* Device size in bytes */
186 unsigned long sector_size; /* byte size of sector */
187 int num_sectors; /* Num sectors of this size */
188 } erase_block[8]; /* Max of 256, but 8 is good */
191 struct flash_name_from_id {
192 unsigned short fnfi_id;
198 int cfi_flash_init(flash_device_info_t **flash_info);
199 static int cfi_flash_sector_erase_int(unsigned short sector);
200 static int cfi_flash_read_buf(unsigned short sector, int offset,
201 unsigned char *buffer, int numbytes);
202 static int cfi_flash_write_buf(unsigned short sector, int offset,
203 unsigned char *buffer, int numbytes);
204 static int cfi_flash_get_numsectors(void);
205 static int cfi_flash_get_sector_size(unsigned short sector);
206 static unsigned char *cfi_flash_get_memptr(unsigned short sector);
207 static int cfi_flash_get_blk(int addr);
208 static int cfi_flash_get_total_size(void);
209 static void cfi_flash_command(int command, unsigned short sector, int offset,
210 unsigned short data);
211 static int cfi_flash_write(unsigned short sector, int offset, unsigned char *buf,
213 static int cfi_flash_wait(unsigned short sector, int offset,unsigned short data);
214 static unsigned short cfi_flash_get_device_id(void);
215 static int cfi_flash_get_cfi(struct cfi_query *query, unsigned short *cfi_struct,
220 static flash_device_info_t flash_cfi_dev =
224 cfi_flash_sector_erase_int,
227 cfi_flash_get_numsectors,
228 cfi_flash_get_sector_size,
229 cfi_flash_get_memptr,
231 cfi_flash_get_total_size,
232 cfi_flash_get_total_size
235 /*********************************************************************/
236 /* 'meminfo' should be a pointer, but most C compilers will not */
237 /* allocate static storage for a pointer without calling */
238 /* non-portable functions such as 'new'. We also want to avoid */
239 /* the overhead of passing this pointer for every driver call. */
240 /* Systems with limited heap space will need to do this. */
241 /*********************************************************************/
242 static struct flashinfo meminfo; /* Flash information structure */
243 static int flashFamily = FLASH_UNDEFINED;
244 static int totalSize = 0;
245 static struct cfi_query query;
247 static unsigned short cfi_data_struct_29W160[] = {
248 0x0020, 0x0049, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
249 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
250 0x0051, 0x0052, 0x0059, 0x0002, 0x0000, 0x0040, 0x0000, 0x0000,
251 0x0000, 0x0000, 0x0000, 0x0027, 0x0036, 0x0000, 0x0000, 0x0004,
252 0x0000, 0x000a, 0x0000, 0x0004, 0x0000, 0x0003, 0x0000, 0x0015,
253 0x0002, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0x0000, 0x0040,
254 0x0000, 0x0001, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0080,
255 0x0000, 0x001e, 0x0000, 0x0000, 0x0001, 0xffff, 0xffff, 0xffff,
256 0x0050, 0x0052, 0x0049, 0x0031, 0x0030, 0x0000, 0x0002, 0x0001,
257 0x0001, 0x0004, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0x0002,
258 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
259 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
260 0xffff, 0x0888, 0x252b, 0x8c84, 0x7dbc, 0xffff, 0xffff, 0xffff,
261 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
262 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
263 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
266 static UINT16 cfi_data_struct_29W200[] = {
267 0x0020, 0x0049, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
268 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
269 0x0051, 0x0052, 0x0059, 0x0002, 0x0000, 0x0040, 0x0000, 0x0000,
270 0x0000, 0x0000, 0x0000, 0x0027, 0x0036, 0x0000, 0x0000, 0x0004,
271 0x0000, 0x000a, 0x0000, 0x0004, 0x0000, 0x0003, 0x0000, 0x0015,
272 0x0002, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0x0000, 0x0040,
273 0x0000, 0x0001, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0080,
274 0x0000, 0x0002, 0x0000, 0x0000, 0x0001, 0xffff, 0xffff, 0xffff,
275 0x0050, 0x0052, 0x0049, 0x0031, 0x0030, 0x0000, 0x0002, 0x0001,
276 0x0001, 0x0004, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0x0002,
277 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
278 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
279 0xffff, 0x0888, 0x252b, 0x8c84, 0x7dbc, 0xffff, 0xffff, 0xffff,
280 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
281 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
282 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
285 static UINT16 cfi_data_struct_26LV800B[] = {
286 0x0020, 0x0049, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
287 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
288 0x0051, 0x0052, 0x0059, 0x0002, 0x0000, 0x0040, 0x0000, 0x0000,
289 0x0000, 0x0000, 0x0000, 0x0027, 0x0036, 0x0000, 0x0000, 0x0004,
290 0x0000, 0x000a, 0x0000, 0x0004, 0x0000, 0x0003, 0x0000, 0x0015,
291 0x0002, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0x0000, 0x0040,
292 0x0000, 0x0001, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0080,
293 0x0000, 0x000e, 0x0000, 0x0000, 0x0001, 0xffff, 0xffff, 0xffff,
294 0x0050, 0x0052, 0x0049, 0x0031, 0x0030, 0x0000, 0x0002, 0x0001,
295 0x0001, 0x0004, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0x0002,
296 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
297 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
298 0xffff, 0x0888, 0x252b, 0x8c84, 0x7dbc, 0xffff, 0xffff, 0xffff,
299 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
300 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
301 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
305 /*********************************************************************/
306 /* Init_flash is used to build a sector table from the information */
307 /* provided through the CFI query. This information is translated */
308 /* from erase_block information to base:offset information for each */
309 /* individual sector. This information is then stored in the meminfo */
310 /* structure, and used throughout the driver to access sector */
313 /* This is more efficient than deriving the sector base:offset */
314 /* information every time the memory map switches (since on the */
315 /* development platform can only map 64k at a time). If the entire */
316 /* flash memory array can be mapped in, then the addition static */
317 /* allocation for the meminfo structure can be eliminated, but the */
318 /* drivers will have to be re-written. */
320 /* The meminfo struct occupies 653 bytes of heap space, depending */
321 /* on the value of the define MAXSECTORS. Adjust to suit */
323 /*********************************************************************/
324 int cfi_flash_init(flash_device_info_t **flash_info)
326 struct flash_name_from_id fnfi[] = CFI_FLASH_DEVICES;
327 struct flash_name_from_id *fnfi_ptr;
328 int i=0, j=0, count=0;
330 unsigned short device_id;
331 int flipCFIGeometry = FALSE;
333 *flash_info = &flash_cfi_dev;
336 * a single 8k sector for sector 0. This is to allow
337 * the system to perform memory mapping to the device,
338 * even though the actual physical layout is unknown.
339 * Once mapped in, the CFI query will produce all
340 * relevant information.
345 meminfo.bank1start = 0;
346 meminfo.bank2start = 0;
348 meminfo.sec[0].size = 8192;
349 meminfo.sec[0].base = 0x00000;
350 meminfo.sec[0].bank = 1;
352 cfi_flash_command(FLASH_RESET, 0, 0, 0);
354 flash_cfi_dev.flash_device_id = device_id = cfi_flash_get_device_id();
355 flash_cfi_dev.flash_device_name[0] = '\0';
362 flashFamily = FLASH_INTEL;
379 // add ST flash device id here
381 // add ST flash device id here
382 flashFamily = FLASH_AMD;
389 // add SST flash device id here
391 // add SST flash device id here
393 flashFamily = FLASH_SST;
396 return FLASH_API_ERROR;
399 if (cfi_flash_get_cfi(&query, 0, flashFamily) == -1) {
403 cfi_flash_get_cfi(&query, cfi_data_struct_29W160, flashFamily);
406 cfi_flash_get_cfi(&query, cfi_data_struct_29W200, flashFamily);
409 cfi_flash_get_cfi(&query, cfi_data_struct_26LV800B, flashFamily);
410 strcpy( flash_cfi_dev.flash_device_name, "MX26LV800B" );
413 return FLASH_API_ERROR;
417 // need to determine if it top or bottom boot here
437 flipCFIGeometry = FALSE;
448 // add SST and ST flash device id here
451 // add SST and ST flash device id here
452 flipCFIGeometry = TRUE;
455 return FLASH_API_ERROR;
458 count=0;basecount=0L;
460 if (!flipCFIGeometry)
463 for (i=0; i<query.num_erase_blocks && basecount < query.device_size; i++) {
464 for(j=0; j<query.erase_block[i].num_sectors; j++) {
465 meminfo.sec[count].size = (int) query.erase_block[i].sector_size;
466 meminfo.sec[count].base = (int) basecount;
467 basecount += (int) query.erase_block[i].sector_size;
474 for (i = (query.num_erase_blocks - 1); i >= 0 && basecount < query.device_size; i--) {
475 for(j=0; j<query.erase_block[i].num_sectors; j++) {
476 meminfo.sec[count].size = (int) query.erase_block[i].sector_size;
477 meminfo.sec[count].base = (int) basecount;
478 basecount += (int) query.erase_block[i].sector_size;
484 meminfo.nsect = count;
485 totalSize = meminfo.sec[count-1].base + meminfo.sec[count-1].size;
487 if( flash_cfi_dev.flash_device_name[0] == '\0' ) {
488 for( fnfi_ptr = fnfi; fnfi_ptr->fnfi_id != 0; fnfi_ptr++ ) {
489 if( fnfi_ptr->fnfi_id == device_id ) {
490 strcpy( flash_cfi_dev.flash_device_name, fnfi_ptr->fnfi_name );
496 return (FLASH_API_OK);
499 /*********************************************************************/
500 /* Flash_sector_erase_int() is identical to flash_sector_erase(), */
501 /* except it will wait until the erase is completed before returning */
502 /* control to the calling function. This can be used in cases which */
503 /* require the program to hold until a sector is erased, without */
504 /* adding the wait check external to this function. */
505 /*********************************************************************/
506 static int cfi_flash_sector_erase_int(unsigned short sector)
510 for( i = 0; i < 3; i++ ) {
511 cfi_flash_command(FLASH_SERASE, sector, 0, 0);
512 if (cfi_flash_wait(sector, 0, 0xffff) == STATUS_READY)
516 return(FLASH_API_OK);
519 /*********************************************************************/
520 /* flash_read_buf() reads buffer of data from the specified */
521 /* offset from the sector parameter. */
522 /*********************************************************************/
523 static int cfi_flash_read_buf(unsigned short sector, int offset,
524 unsigned char *buffer, int numbytes)
528 fwp = (unsigned char *) cfi_flash_get_memptr(sector);
531 *buffer++ = *(fwp + offset);
536 return (FLASH_API_OK);
539 /*********************************************************************/
540 /* flash_write_buf() utilizes */
541 /* the unlock bypass mode of the flash device. This can remove */
542 /* significant overhead from the bulk programming operation, and */
543 /* when programming bulk data a sizeable performance increase can be */
545 /*********************************************************************/
546 static int cfi_flash_write_buf(unsigned short sector, int offset,
547 unsigned char *buffer, int numbytes)
549 int ret = FLASH_API_ERROR;
551 unsigned char *p = cfi_flash_get_memptr(sector) + offset;
553 printk("Flash writing sector %d %x\n", sector, p);
555 /* After writing the flash block, compare the contents to the source
556 * buffer. Try to write the sector successfully up to three times.
558 for( i = 0; i < 3; i++ ) {
559 ret = cfi_flash_write(sector, offset, buffer, numbytes);
560 if( !memcmp( p, buffer, numbytes ) )
562 /* Erase and try again */
563 flash_sector_erase_int(sector);
564 ret = FLASH_API_ERROR;
566 // printk( "%c", i==0 ? '*' : ' ' );
568 if( ret == FLASH_API_ERROR )
569 printk( "Flash write sector %d error. Verify failed\n", sector );
574 /*********************************************************************/
575 /* Usefull funtion to return the number of sectors in the device. */
576 /* Can be used for functions which need to loop among all the */
577 /* sectors, or wish to know the number of the last sector. */
578 /*********************************************************************/
579 static int cfi_flash_get_numsectors(void)
581 return meminfo.nsect;
584 /*********************************************************************/
585 /* flash_get_sector_size() is provided for cases in which the size */
586 /* of a sector is required by a host application. The sector size */
587 /* (in bytes) is returned in the data location pointed to by the */
588 /* 'size' parameter. */
589 /*********************************************************************/
590 static int cfi_flash_get_sector_size(unsigned short sector)
592 return meminfo.sec[sector].size;
595 /*********************************************************************/
596 /* The purpose of flash_get_memptr() is to return a memory pointer */
597 /* which points to the beginning of memory space allocated for the */
598 /* flash. All function pointers are then referenced from this */
601 /* Different systems will implement this in different ways: */
602 /* possibilities include: */
603 /* - A direct memory pointer */
604 /* - A pointer to a memory map */
605 /* - A pointer to a hardware port from which the linear */
606 /* address is translated */
607 /* - Output of an MMU function / service */
609 /* Also note that this function expects the pointer to a specific */
610 /* sector of the device. This can be provided by dereferencing */
611 /* the pointer from a translated offset of the sector from a */
612 /* global base pointer (e.g. flashptr = base_pointer + sector_offset)*/
614 /* Important: Many AMD flash devices need both bank and or sector */
615 /* address bits to be correctly set (bank address bits are A18-A16, */
616 /* and sector address bits are A18-A12, or A12-A15). Flash parts */
617 /* which do not need these bits will ignore them, so it is safe to */
618 /* assume that every part will require these bits to be set. */
619 /*********************************************************************/
620 static unsigned char *cfi_flash_get_memptr(unsigned short sector)
622 unsigned char *memptr = (unsigned char*)
623 (FLASH_BASE + meminfo.sec[sector].base);
628 /*********************************************************************/
629 /* The purpose of flash_get_blk() is to return a the block number */
630 /* for a given memory address. */
631 /*********************************************************************/
632 static int cfi_flash_get_blk(int addr)
635 int last_blk = cfi_flash_get_numsectors();
636 int relative_addr = addr - (int) FLASH_BASE;
638 for(blk_start=0, i=0; i < relative_addr && blk_start < last_blk; blk_start++)
639 i += cfi_flash_get_sector_size(blk_start);
641 if( i > relative_addr )
643 blk_start--; // last blk, dec by 1
646 if( blk_start == last_blk )
648 printk("Address is too big.\n");
655 /************************************************************************/
656 /* The purpose of flash_get_total_size() is to return the total size of */
658 /************************************************************************/
659 static int cfi_flash_get_total_size(void)
664 /*********************************************************************/
665 /* Flash_command() is the main driver function. It performs */
666 /* every possible command available to AMD B revision */
667 /* flash parts. Note that this command is not used directly, but */
668 /* rather called through the API wrapper functions provided below. */
669 /*********************************************************************/
670 static void cfi_flash_command(int command, unsigned short sector, int offset,
673 volatile unsigned short *flashptr;
674 volatile unsigned short *flashbase;
676 flashptr = (unsigned short *) cfi_flash_get_memptr(sector);
677 flashbase = (unsigned short *) cfi_flash_get_memptr(0);
679 switch (flashFamily) {
680 case FLASH_UNDEFINED:
681 /* These commands should work for AMD, Intel and SST flashes */
688 flashptr[0x5555] = 0xAA; /* unlock 1 */
689 flashptr[0x2AAA] = 0x55; /* unlock 2 */
690 flashptr[0x5555] = 0x90;
693 flashbase[0x5555] = 0xAA; /* unlock 1 */
694 flashbase[0x2AAA] = 0x55; /* unlock 2 */
695 flashbase[0x5555] = 0x90;
707 flashptr[0x555] = 0xAA; /* unlock 1 */
708 flashptr[0x2AA] = 0x55; /* unlock 2 */
709 flashptr[0x555] = 0x90;
712 flashptr[0x55] = 0x98;
715 flashptr[0x555] = 0xAA; /* unlock 1 */
716 flashptr[0x2AA] = 0x55; /* unlock 2 */
717 flashptr[0x555] = 0x20;
721 flashptr[offset/2] = data;
728 flashptr[0x555] = 0xAA; /* unlock 1 */
729 flashptr[0x2AA] = 0x55; /* unlock 2 */
730 flashptr[0x555] = 0x80;
731 flashptr[0x555] = 0xAA;
732 flashptr[0x2AA] = 0x55;
752 flashptr[offset/2] = data;
755 //flashptr[0] = 0x60; Block Unlock is not required.
756 //flashptr[0] = 0xD0;
767 flashbase[0x5555] = 0xAA; /* unlock 1 */
768 flashbase[0x2AAA] = 0x55; /* unlock 2 */
769 flashbase[0x5555] = 0xf0;
772 flashbase[0x5555] = 0xAA; /* unlock 1 */
773 flashbase[0x2AAA] = 0x55; /* unlock 2 */
774 flashbase[0x5555] = 0x90;
777 flashbase[0x5555] = 0xAA; /* unlock 1 */
778 flashbase[0x2AAA] = 0x55; /* unlock 2 */
779 flashbase[0x5555] = 0x98;
784 flashbase[0x5555] = 0xAA; /* unlock 1 */
785 flashbase[0x2AAA] = 0x55; /* unlock 2 */
786 flashbase[0x5555] = 0xa0;
787 flashptr[offset/2] = data;
792 flashbase[0x5555] = 0xAA; /* unlock 1 */
793 flashbase[0x2AAA] = 0x55; /* unlock 2 */
794 flashbase[0x5555] = 0x80;
795 flashbase[0x5555] = 0xAA;
796 flashbase[0x2AAA] = 0x55;
808 /*********************************************************************/
809 /* flash_write extends the functionality of flash_program() by */
810 /* providing an faster way to program multiple data words, without */
811 /* needing the function overhead of looping algorithms which */
812 /* program word by word. This function utilizes fast pointers */
813 /* to quickly loop through bulk data. */
814 /*********************************************************************/
815 static int cfi_flash_write(unsigned short sector, int offset, unsigned char *buf,
819 src = (unsigned short *)buf;
821 if ((nbytes | offset) & 1) {
822 return FLASH_API_ERROR;
825 cfi_flash_command(FLASH_UB, 0, 0, 0);
827 cfi_flash_command(FLASH_PROG, sector, offset, *src);
828 if (cfi_flash_wait(sector, offset, *src) != STATUS_READY)
834 cfi_flash_command(FLASH_UBRESET, 0, 0, 0);
836 return (unsigned char*)src - buf;
839 /*********************************************************************/
840 /* flash_wait utilizes the DQ6, DQ5, and DQ2 polling algorithms */
841 /* described in the flash data book. It can quickly ascertain the */
842 /* operational status of the flash device, and return an */
843 /* appropriate status code (defined in flash.h) */
844 /*********************************************************************/
845 static int cfi_flash_wait(unsigned short sector, int offset, unsigned short data)
847 volatile unsigned short *flashptr; /* flash window */
850 flashptr = (unsigned short *) cfi_flash_get_memptr(sector);
852 if (flashFamily == FLASH_AMD || flashFamily == FLASH_SST) {
853 /* 6338 and 6358 for different reasons do a 'double read' when reading 16 bit from EBI */
854 #if defined(_BCM96338_) || defined(CONFIG_BCM96338) || defined(_BCM96358_) || defined(CONFIG_BCM96358)
856 d1 = flashptr[offset/2];
859 } while (!(d1 & 0x20));
861 d1 = flashptr[offset/2];
865 /* If the word written does not yet compare, try for another 100ms.
866 * This check is done for SST39VF800A.
869 for( i = 0; i < 10000; i++ ) {
870 d1 = flashptr[offset/2];
876 d1 = flashptr[offset/2];
879 cfi_flash_command(FLASH_RESET, 0, 0, 0);
880 return STATUS_TIMEOUT;
885 d1 = *flashptr; /* read data */
886 d1 ^= *flashptr; /* read it again and see what toggled */
887 if (d1 == 0) /* no toggles, nothing's happening */
889 } while (!(d1 & 0x20));
891 d1 = *flashptr; /* read data */
892 d1 ^= *flashptr; /* read it again and see what toggled */
895 cfi_flash_command(FLASH_RESET, 0, 0, 0);
896 return STATUS_TIMEOUT;
899 } else if (flashFamily == FLASH_INTEL) {
901 /* Wait for completion */
902 while(!(*flashptr & 0x80));
903 if (*flashptr & 0x30) {
905 printk("CFI: Wait error &d\n", *flashptr);
906 cfi_flash_command(FLASH_RESET, 0, 0, 0);
907 return STATUS_TIMEOUT;
910 cfi_flash_command(FLASH_RESET, 0, 0, 0);
916 /*********************************************************************/
917 /* flash_get_device_id() will perform an autoselect sequence on the */
918 /* flash device, and return the device id of the component. */
919 /* This function automatically resets to read mode. */
920 /*********************************************************************/
921 static unsigned short cfi_flash_get_device_id(void)
923 volatile unsigned short *fwp; /* flash window */
924 unsigned short answer;
926 fwp = (unsigned short *) cfi_flash_get_memptr(0);
928 cfi_flash_command(FLASH_READ_ID, 0, 0, 0);
930 if (answer == ID_AM29LV320M) {
931 answer = *(fwp + 0xe);
932 answer = *(fwp + 0xf);
935 cfi_flash_command(FLASH_RESET, 0, 0, 0);
936 return( (unsigned short) answer );
939 /*********************************************************************/
940 /* flash_get_cfi() is the main CFI workhorse function. Due to it's */
941 /* complexity and size it need only be called once upon */
942 /* initializing the flash system. Once it is called, all operations */
943 /* are performed by looking at the meminfo structure. */
944 /* All possible care was made to make this algorithm as efficient as */
945 /* possible. 90% of all operations are memory reads, and all */
946 /* calculations are done using bit-shifts when possible */
947 /*********************************************************************/
948 static int cfi_flash_get_cfi(struct cfi_query *query, unsigned short *cfi_struct,
951 volatile unsigned short *fwp; /* flash window */
954 cfi_flash_command(FLASH_CFIQUERY, 0, 0, 0);
957 fwp = (unsigned short *) cfi_flash_get_memptr(0);
961 /* Initial house-cleaning */
962 for(i=0; i < 8; i++) {
963 query->erase_block[i].sector_size = 0;
964 query->erase_block[i].num_sectors = 0;
967 /* If not 'QRY', then we dont have a CFI enabled device in the socket */
968 if( fwp[0x10] != 'Q' &&
971 cfi_flash_command(FLASH_RESET, 0, 0, 0);
972 return(FLASH_API_ERROR);
976 query->device_size = (int) (((int)1) << temp);
978 query->num_erase_blocks = fwp[0x2C];
979 if(flashFamily == FLASH_SST)
980 query->num_erase_blocks = 1;
982 for(i=0; i < query->num_erase_blocks; i++) {
983 query->erase_block[i].num_sectors =
984 fwp[(0x2D+(4*i))] + (fwp[0x2E + (4*i)] << 8);
985 query->erase_block[i].num_sectors++;
986 query->erase_block[i].sector_size =
987 256 * (256 * fwp[(0x30+(4*i))] + fwp[(0x2F+(4*i))]);
990 cfi_flash_command(FLASH_RESET, 0, 0, 0);
991 return(FLASH_API_OK);