2 * (C) Copyright 2002-2004
3 * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
5 * Copyright (C) 2003 Arabella Software Ltd.
6 * Yuli Barcohen <yuli@arabellasw.com>
12 * Tolunay Orkun <listmember@orkun.us>
14 * See file CREDITS for list of people who contributed to this
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 /* The DEBUG define must be before common to enable debugging */
38 #include <asm/byteorder.h>
39 #include <environment.h>
43 #include <cfi_flash_new.h>
48 * This file implements a Common Flash Interface (CFI) driver for barebox.
49 * The width of the port and the width of the chips are determined at initialization.
50 * These widths are used to calculate the address for access CFI data structures.
53 * JEDEC Standard JESD68 - Common Flash Interface (CFI)
54 * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
55 * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
56 * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
57 * AMD CFI Specification, Release 2.0 December 1, 2001
58 * AMD/Spansion Application Note: Migration from Single-byte to Three-byte
59 * Device IDs, Publication Number 25538 Revision A, November 8, 2001
63 #define NUM_ERASE_REGIONS 4 /* max. number of erase regions */
65 static uint flash_offset_cfi
[2]={FLASH_OFFSET_CFI
,FLASH_OFFSET_CFI_ALT
};
68 * Check if chip width is defined. If not, start detecting with 8bit.
70 #ifndef CFG_FLASH_CFI_WIDTH
71 #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT
79 static void flash_add_byte (flash_info_t
* info
, cfiword_t
* cword
, uchar c
)
81 #if defined(__LITTLE_ENDIAN)
84 unsigned long long ll
;
87 if (bankwidth_is_1(info
)) {
89 } else if (bankwidth_is_2(info
)) {
90 #if defined(__LITTLE_ENDIAN)
93 cword
->w
= (cword
->w
>> 8) | w
;
95 cword
->w
= (cword
->w
<< 8) | c
;
97 } else if (bankwidth_is_4(info
)) {
98 #if defined(__LITTLE_ENDIAN)
101 cword
->l
= (cword
->l
>> 8) | l
;
103 cword
->l
= (cword
->l
<< 8) | c
;
105 } else if (bankwidth_is_8(info
)) {
106 #if defined(__LITTLE_ENDIAN)
109 cword
->ll
= (cword
->ll
>> 8) | ll
;
111 cword
->ll
= (cword
->ll
<< 8) | c
;
116 static int flash_write_cfiword (flash_info_t
* info
, ulong dest
,
123 ctladdr
.cp
= flash_make_addr (info
, 0, 0);
124 cptr
.cp
= (uchar
*) dest
;
127 /* Check if Flash is (sufficiently) erased */
128 if (bankwidth_is_1(info
)) {
129 flag
= ((cptr
.cp
[0] & cword
.c
) == cword
.c
);
130 } else if (bankwidth_is_2(info
)) {
131 flag
= ((cptr
.wp
[0] & cword
.w
) == cword
.w
);
132 } else if (bankwidth_is_4(info
)) {
133 flag
= ((cptr
.lp
[0] & cword
.l
) == cword
.l
);
134 } else if (bankwidth_is_8(info
)) {
135 flag
= ((cptr
.llp
[0] & cword
.ll
) == cword
.ll
);
142 /* Disable interrupts which might cause a timeout here */
143 // flag = disable_interrupts ();
145 info
->cfi_cmd_set
->flash_prepare_write(info
);
147 if (bankwidth_is_1(info
)) {
148 cptr
.cp
[0] = cword
.c
;
149 } else if (bankwidth_is_2(info
)) {
150 cptr
.wp
[0] = cword
.w
;
151 } else if (bankwidth_is_4(info
)) {
152 cptr
.lp
[0] = cword
.l
;
153 } else if (bankwidth_is_8(info
)) {
154 cptr
.llp
[0] = cword
.ll
;
157 /* re-enable interrupts if necessary */
159 enable_interrupts ();
161 return flash_status_check (info
, find_sector (info
, dest
),
162 info
->write_tout
, "write");
169 void print_longlong (char *str
, unsigned long long data
)
174 cp
= (unsigned char *) &data
;
175 for (i
= 0; i
< 8; i
++)
176 sprintf (&str
[i
* 2], "%2.2x", *cp
++);
179 static void flash_printqry (flash_info_t
* info
, flash_sect_t sect
)
184 for (x
= 0; x
< 0x40; x
+= 16U / info
->portwidth
) {
186 flash_make_addr (info
, sect
,
187 x
+ FLASH_OFFSET_CFI_RESP
);
188 debug ("%p : ", cptr
.cp
);
189 for (y
= 0; y
< 16; y
++) {
190 debug ("%2.2x ", cptr
.cp
[y
]);
193 for (y
= 0; y
< 16; y
++) {
194 if (cptr
.cp
[y
] >= 0x20 && cptr
.cp
[y
] <= 0x7e) {
195 debug ("%c", cptr
.cp
[y
]);
206 * read a short word by swapping for ppc format.
208 static ushort
flash_read_ushort (flash_info_t
* info
, flash_sect_t sect
, uint offset
)
216 addr
= flash_make_addr (info
, sect
, offset
);
219 debug ("ushort addr is at %p info->portwidth = %d\n", addr
,
221 for (x
= 0; x
< 2 * info
->portwidth
; x
++) {
222 debug ("addr[%x] = 0x%x\n", x
, addr
[x
]);
225 #if defined(__LITTLE_ENDIAN)
226 retval
= ((addr
[(info
->portwidth
)] << 8) | addr
[0]);
228 retval
= ((addr
[(2 * info
->portwidth
) - 1] << 8) |
229 addr
[info
->portwidth
- 1]);
232 debug ("retval = 0x%x\n", retval
);
237 * read a long word by picking the least significant byte of each maximum
238 * port size word. Swap for ppc format.
240 static ulong
flash_read_long (flash_info_t
* info
, flash_sect_t sect
, uint offset
)
248 addr
= flash_make_addr (info
, sect
, offset
);
251 debug ("long addr is at %p info->portwidth = %d\n", addr
,
253 for (x
= 0; x
< 4 * info
->portwidth
; x
++) {
254 debug ("addr[%x] = 0x%x\n", x
, addr
[x
]);
257 #if defined(__LITTLE_ENDIAN)
258 retval
= (addr
[0] << 16) | (addr
[(info
->portwidth
)] << 24) |
259 (addr
[(2 * info
->portwidth
)]) | (addr
[(3 * info
->portwidth
)] << 8);
261 retval
= (addr
[(2 * info
->portwidth
) - 1] << 24) |
262 (addr
[(info
->portwidth
) - 1] << 16) |
263 (addr
[(4 * info
->portwidth
) - 1] << 8) |
264 addr
[(3 * info
->portwidth
) - 1];
270 * detect if flash is compatible with the Common Flash Interface (CFI)
271 * http://www.jedec.org/download/search/jesd68.pdf
274 static int flash_detect_cfi (flash_info_t
* info
)
277 debug ("flash detect cfi\n");
279 for (info
->portwidth
= CFG_FLASH_CFI_WIDTH
;
280 info
->portwidth
<= FLASH_CFI_64BIT
; info
->portwidth
<<= 1) {
281 for (info
->chipwidth
= FLASH_CFI_BY8
;
282 info
->chipwidth
<= info
->portwidth
;
283 info
->chipwidth
<<= 1) {
284 flash_write_cmd (info
, 0, 0, info
->cmd_reset
);
285 for (cfi_offset
=0; cfi_offset
< sizeof(flash_offset_cfi
)/sizeof(uint
); cfi_offset
++) {
286 flash_write_cmd (info
, 0, flash_offset_cfi
[cfi_offset
], FLASH_CMD_CFI
);
287 if (flash_isequal (info
, 0, FLASH_OFFSET_CFI_RESP
, 'Q')
288 && flash_isequal (info
, 0, FLASH_OFFSET_CFI_RESP
+ 1, 'R')
289 && flash_isequal (info
, 0, FLASH_OFFSET_CFI_RESP
+ 2, 'Y')) {
290 info
->interface
= flash_read_ushort (info
, 0, FLASH_OFFSET_INTERFACE
);
291 info
->cfi_offset
=flash_offset_cfi
[cfi_offset
];
292 debug ("device interface is %d\n",
294 debug ("found port %d chip %d ",
295 info
->portwidth
, info
->chipwidth
);
296 debug ("port %d bits chip %d bits\n",
297 info
->portwidth
<< CFI_FLASH_SHIFT_WIDTH
,
298 info
->chipwidth
<< CFI_FLASH_SHIFT_WIDTH
);
304 debug ("not found\n");
309 * The following code cannot be run from FLASH!
311 static ulong
flash_get_size (flash_info_t
*info
, ulong base
)
314 flash_sect_t sect_cnt
;
315 unsigned long sector
;
318 uchar num_erase_regions
;
319 int erase_region_size
;
320 int erase_region_count
;
321 int geometry_reversed
= 0;
324 info
->cfi_version
= 0;
325 #ifdef CFG_FLASH_PROTECTION
326 info
->legacy_unlock
= 0;
329 /* first only malloc space for the first sector */
330 info
->start
= malloc(sizeof(ulong
));
332 info
->start
[0] = base
;
335 if (flash_detect_cfi (info
)) {
336 info
->vendor
= flash_read_ushort (info
, 0,
337 FLASH_OFFSET_PRIMARY_VENDOR
);
338 switch (info
->vendor
) {
339 #ifdef CONFIG_DRIVER_CFI_INTEL
340 case CFI_CMDSET_INTEL_EXTENDED
:
341 case CFI_CMDSET_INTEL_STANDARD
:
342 info
->cfi_cmd_set
= &cfi_cmd_set_intel
;
345 #ifdef CONFIG_DRIVER_CFI_AMD
346 case CFI_CMDSET_AMD_STANDARD
:
347 case CFI_CMDSET_AMD_EXTENDED
:
348 info
->cfi_cmd_set
= &cfi_cmd_set_amd
;
352 printf("unsupported vendor\n");
355 info
->cfi_cmd_set
->flash_read_jedec_ids (info
);
356 flash_write_cmd (info
, 0, info
->cfi_offset
, FLASH_CMD_CFI
);
357 num_erase_regions
= flash_read_uchar (info
,
358 FLASH_OFFSET_NUM_ERASE_REGIONS
);
359 info
->ext_addr
= flash_read_ushort (info
, 0,
360 FLASH_OFFSET_EXT_QUERY_T_P_ADDR
);
361 if (info
->ext_addr
) {
362 info
->cfi_version
= (ushort
) flash_read_uchar (info
,
363 info
->ext_addr
+ 3) << 8;
364 info
->cfi_version
|= (ushort
) flash_read_uchar (info
,
368 flash_printqry (info
, 0);
370 switch (info
->vendor
) {
371 case CFI_CMDSET_INTEL_STANDARD
:
372 case CFI_CMDSET_INTEL_EXTENDED
:
374 info
->cmd_reset
= FLASH_CMD_RESET
;
375 #ifdef CFG_FLASH_PROTECTION
376 /* read legacy lock/unlock bit from intel flash */
377 if (info
->ext_addr
) {
378 info
->legacy_unlock
= flash_read_uchar (info
,
379 info
->ext_addr
+ 5) & 0x08;
383 case CFI_CMDSET_AMD_STANDARD
:
384 case CFI_CMDSET_AMD_EXTENDED
:
385 info
->cmd_reset
= AMD_CMD_RESET
;
386 /* check if flash geometry needs reversal */
387 if (num_erase_regions
<= 1)
389 /* reverse geometry if top boot part */
390 if (info
->cfi_version
< 0x3131) {
391 /* CFI < 1.1, try to guess from device id */
392 if ((info
->device_id
& 0x80) != 0) {
393 geometry_reversed
= 1;
397 /* CFI >= 1.1, deduct from top/bottom flag */
398 /* note: ext_addr is valid since cfi_version > 0 */
399 if (flash_read_uchar(info
, info
->ext_addr
+ 0xf) == 3) {
400 geometry_reversed
= 1;
405 debug ("manufacturer is %d\n", info
->vendor
);
406 debug ("manufacturer id is 0x%x\n", info
->manufacturer_id
);
407 debug ("device id is 0x%x\n", info
->device_id
);
408 debug ("device id2 is 0x%x\n", info
->device_id2
);
409 debug ("cfi version is 0x%04x\n", info
->cfi_version
);
411 size_ratio
= info
->portwidth
/ info
->chipwidth
;
412 /* if the chip is x8/x16 reduce the ratio by half */
413 if ((info
->interface
== FLASH_CFI_X8X16
)
414 && (info
->chipwidth
== FLASH_CFI_BY8
)) {
417 debug ("size_ratio %d port %d bits chip %d bits\n",
418 size_ratio
, info
->portwidth
<< CFI_FLASH_SHIFT_WIDTH
,
419 info
->chipwidth
<< CFI_FLASH_SHIFT_WIDTH
);
420 debug ("found %d erase regions\n", num_erase_regions
);
424 for (i
= 0; i
< num_erase_regions
; i
++) {
425 if (i
> NUM_ERASE_REGIONS
) {
426 printf ("%d erase regions found, only %d used\n",
427 num_erase_regions
, NUM_ERASE_REGIONS
);
430 if (geometry_reversed
)
431 tmp
= flash_read_long (info
, 0,
432 FLASH_OFFSET_ERASE_REGIONS
+
433 (num_erase_regions
- 1 - i
) * 4);
435 tmp
= flash_read_long (info
, 0,
436 FLASH_OFFSET_ERASE_REGIONS
+
439 (tmp
& 0xffff) ? ((tmp
& 0xffff) * 256) : 128;
441 erase_region_count
= (tmp
& 0xffff) + 1;
442 debug ("erase_region_count = %d erase_region_size = %d\n",
443 erase_region_count
, erase_region_size
);
445 /* increase the space malloced for the sector start addresses */
446 info
->start
= realloc(info
->start
, sizeof(ulong
) * (erase_region_count
+ sect_cnt
));
447 info
->protect
= realloc(info
->protect
, sizeof(uchar
) * (erase_region_count
+ sect_cnt
));
449 for (j
= 0; j
< erase_region_count
; j
++) {
450 info
->start
[sect_cnt
] = sector
;
451 sector
+= (erase_region_size
* size_ratio
);
454 * Only read protection status from supported devices (intel...)
456 switch (info
->vendor
) {
457 case CFI_CMDSET_INTEL_EXTENDED
:
458 case CFI_CMDSET_INTEL_STANDARD
:
459 info
->protect
[sect_cnt
] =
460 flash_isset (info
, sect_cnt
,
461 FLASH_OFFSET_PROTECT
,
462 FLASH_STATUS_PROTECT
);
465 info
->protect
[sect_cnt
] = 0; /* default: not protected */
472 info
->sector_count
= sect_cnt
;
473 /* multiply the size by the number of chips */
474 info
->size
= (1 << flash_read_uchar (info
, FLASH_OFFSET_SIZE
)) * size_ratio
;
475 info
->buffer_size
= (1 << flash_read_ushort (info
, 0, FLASH_OFFSET_BUFFER_SIZE
));
476 tmp
= 1 << flash_read_uchar (info
, FLASH_OFFSET_ETOUT
);
477 info
->erase_blk_tout
= (tmp
* (1 << flash_read_uchar (info
, FLASH_OFFSET_EMAX_TOUT
)));
478 tmp
= (1 << flash_read_uchar (info
, FLASH_OFFSET_WBTOUT
)) *
479 (1 << flash_read_uchar (info
, FLASH_OFFSET_WBMAX_TOUT
));
480 info
->buffer_write_tout
= tmp
* 1000;
481 tmp
= (1 << flash_read_uchar (info
, FLASH_OFFSET_WTOUT
)) *
482 (1 << flash_read_uchar (info
, FLASH_OFFSET_WMAX_TOUT
));
483 info
->write_tout
= tmp
* 1000;
484 info
->flash_id
= FLASH_MAN_CFI
;
485 if ((info
->interface
== FLASH_CFI_X8X16
) && (info
->chipwidth
== FLASH_CFI_BY8
)) {
486 info
->portwidth
>>= 1; /* XXX - Need to test on x8/x16 in parallel. */
490 flash_write_cmd (info
, 0, 0, info
->cmd_reset
);
494 /* loop through the sectors from the highest address
495 * when the passed address is greater or equal to the sector address
498 flash_sect_t
find_sector (flash_info_t
* info
, ulong addr
)
502 for (sector
= info
->sector_count
- 1; sector
>= 0; sector
--) {
503 if (addr
>= info
->start
[sector
])
509 static int cfi_erase(struct cdev
*cdev
, size_t count
, unsigned long offset
)
511 flash_info_t
*finfo
= (flash_info_t
*)cdev
->priv
;
512 unsigned long start
, end
;
515 printf("%s: erase 0x%08x (size %d)\n", __FUNCTION__
, offset
, count
);
517 start
= find_sector(finfo
, cdev
->dev
->map_base
+ offset
);
518 end
= find_sector(finfo
, cdev
->dev
->map_base
+ offset
+ count
- 1);
520 for (i
= start
; i
<= end
; i
++) {
521 ret
= finfo
->cfi_cmd_set
->flash_erase_one(finfo
, i
);
532 * Copy memory to flash, returns:
535 * 2 - Flash not erased
537 static int write_buff (flash_info_t
* info
, const uchar
* src
, ulong addr
, ulong cnt
)
545 #ifdef CONFIG_CFI_BUFFER_WRITE
548 /* get lower aligned address */
549 /* get lower aligned address */
550 wp
= (addr
& ~(info
->portwidth
- 1));
552 /* handle unaligned start */
553 if ((aln
= addr
- wp
) != 0) {
556 for (i
= 0; i
< aln
; ++i
, ++cp
)
557 flash_add_byte (info
, &cword
, (*(uchar
*) cp
));
559 for (; (i
< info
->portwidth
) && (cnt
> 0); i
++) {
560 flash_add_byte (info
, &cword
, *src
++);
564 for (; (cnt
== 0) && (i
< info
->portwidth
); ++i
, ++cp
)
565 flash_add_byte (info
, &cword
, (*(uchar
*) cp
));
566 if ((rc
= flash_write_cfiword (info
, wp
, cword
)) != 0)
571 /* handle the aligned part */
572 #ifdef CONFIG_CFI_BUFFER_WRITE
573 buffered_size
= (info
->portwidth
/ info
->chipwidth
);
574 buffered_size
*= info
->buffer_size
;
575 while (cnt
>= info
->portwidth
) {
576 /* prohibit buffer write when buffer_size is 1 */
577 if (info
->buffer_size
== 1) {
579 for (i
= 0; i
< info
->portwidth
; i
++)
580 flash_add_byte (info
, &cword
, *src
++);
581 if ((rc
= flash_write_cfiword (info
, wp
, cword
)) != 0)
583 wp
+= info
->portwidth
;
584 cnt
-= info
->portwidth
;
588 /* write buffer until next buffered_size aligned boundary */
589 i
= buffered_size
- (wp
% buffered_size
);
592 if ((rc
= info
->cfi_cmd_set
->flash_write_cfibuffer (info
, wp
, src
, i
)) != ERR_OK
)
594 i
-= i
& (info
->portwidth
- 1);
600 while (cnt
>= info
->portwidth
) {
602 for (i
= 0; i
< info
->portwidth
; i
++) {
603 flash_add_byte (info
, &cword
, *src
++);
605 if ((rc
= flash_write_cfiword (info
, wp
, cword
)) != 0)
607 wp
+= info
->portwidth
;
608 cnt
-= info
->portwidth
;
610 #endif /* CONFIG_CFI_BUFFER_WRITE */
616 * handle unaligned tail bytes
619 for (i
= 0, cp
= wp
; (i
< info
->portwidth
) && (cnt
> 0); ++i
, ++cp
) {
620 flash_add_byte (info
, &cword
, *src
++);
623 for (; i
< info
->portwidth
; ++i
, ++cp
) {
624 flash_add_byte (info
, &cword
, (*(uchar
*) cp
));
627 return flash_write_cfiword (info
, wp
, cword
);
630 static int flash_real_protect (flash_info_t
* info
, long sector
, int prot
)
634 flash_write_cmd (info
, sector
, 0, FLASH_CMD_CLEAR_STATUS
);
635 flash_write_cmd (info
, sector
, 0, FLASH_CMD_PROTECT
);
637 flash_write_cmd (info
, sector
, 0, FLASH_CMD_PROTECT_SET
);
639 flash_write_cmd (info
, sector
, 0, FLASH_CMD_PROTECT_CLEAR
);
642 flash_status_check (info
, sector
, info
->erase_blk_tout
,
643 prot
? "protect" : "unprotect")) == 0) {
645 info
->protect
[sector
] = prot
;
648 * On some of Intel's flash chips (marked via legacy_unlock)
649 * unprotect unprotects all locking.
651 if ((prot
== 0) && (info
->legacy_unlock
)) {
654 for (i
= 0; i
< info
->sector_count
; i
++) {
655 if (info
->protect
[i
])
656 flash_real_protect (info
, i
, 1);
663 static int cfi_protect(struct cdev
*cdev
, size_t count
, unsigned long offset
, int prot
)
665 flash_info_t
*finfo
= (flash_info_t
*)cdev
->priv
;
666 unsigned long start
, end
;
668 const char *action
= (prot
? "protect" : "unprotect");
670 printf("%s: %s 0x%08x (size %d)\n", __FUNCTION__
,
671 action
, cdev
->dev
->map_base
+ offset
, count
);
673 start
= find_sector(finfo
, cdev
->dev
->map_base
+ offset
);
674 end
= find_sector(finfo
, cdev
->dev
->map_base
+ offset
+ count
- 1);
676 for (i
= start
; i
<= end
; i
++) {
677 ret
= flash_real_protect (finfo
, i
, prot
);
686 static ssize_t
cfi_write(struct cdev
*cdev
, const void *buf
, size_t count
, unsigned long offset
, ulong flags
)
688 flash_info_t
*finfo
= (flash_info_t
*)cdev
->priv
;
691 debug("cfi_write: buf=0x%08x addr=0x%08x count=0x%08x\n",buf
, cdev
->dev
->map_base
+ offset
, count
);
693 ret
= write_buff (finfo
, buf
, cdev
->dev
->map_base
+ offset
, count
);
694 return ret
== 0 ? count
: -1;
697 static void cfi_info (struct device_d
* dev
)
699 flash_info_t
*info
= (flash_info_t
*)dev
->priv
;
702 if (info
->flash_id
!= FLASH_MAN_CFI
) {
703 puts ("missing or unknown FLASH type\n");
707 printf ("CFI conformant FLASH (%d x %d)",
708 (info
->portwidth
<< 3), (info
->chipwidth
<< 3));
709 printf (" Size: %ld MB in %d Sectors\n",
710 info
->size
>> 20, info
->sector_count
);
712 switch (info
->vendor
) {
713 case CFI_CMDSET_INTEL_STANDARD
:
714 printf ("Intel Standard");
716 case CFI_CMDSET_INTEL_EXTENDED
:
717 printf ("Intel Extended");
719 case CFI_CMDSET_AMD_STANDARD
:
720 printf ("AMD Standard");
722 case CFI_CMDSET_AMD_EXTENDED
:
723 printf ("AMD Extended");
726 printf ("Unknown (%d)", info
->vendor
);
729 printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x%02X",
730 info
->manufacturer_id
, info
->device_id
);
731 if (info
->device_id
== 0x7E) {
732 printf("%04X", info
->device_id2
);
734 printf ("\n Erase timeout: %ld ms, write timeout: %ld ms\n",
735 info
->erase_blk_tout
,
737 if (info
->buffer_size
> 1) {
738 printf (" Buffer write timeout: %ld ms, buffer size: %d bytes\n",
739 info
->buffer_write_tout
,
743 puts ("\n Sector Start Addresses:");
744 for (i
= 0; i
< info
->sector_count
; ++i
) {
747 #ifdef CFG_FLASH_EMPTY_INFO
752 volatile unsigned long *flash
;
755 * Check if whole sector is erased
757 if (i
!= (info
->sector_count
- 1))
758 size
= info
->start
[i
+ 1] - info
->start
[i
];
760 size
= info
->start
[0] + info
->size
- info
->start
[i
];
762 flash
= (volatile unsigned long *) info
->start
[i
];
763 size
= size
>> 2; /* divide by 4 for longword access */
764 for (k
= 0; k
< size
; k
++) {
765 if (*flash
++ != 0xffffffff) {
771 /* print empty and read-only info */
772 printf (" %08lX %c %s ",
775 info
->protect
[i
] ? "RO" : " ");
777 #else /* ! CFG_FLASH_EMPTY_INFO */
778 printf (" %08lX %s ",
780 info
->protect
[i
] ? "RO" : " ");
789 * flash_read_user_serial - read the OneTimeProgramming cells
791 static void flash_read_user_serial (flash_info_t
* info
, void *buffer
, int offset
,
798 src
= flash_make_addr (info
, 0, FLASH_OFFSET_USER_PROTECTION
);
799 flash_write_cmd (info
, 0, 0, FLASH_CMD_READ_ID
);
800 memcpy (dst
, src
+ offset
, len
);
801 flash_write_cmd (info
, 0, 0, info
->cmd_reset
);
805 * flash_read_factory_serial - read the device Id from the protection area
807 static void flash_read_factory_serial (flash_info_t
* info
, void *buffer
, int offset
,
812 src
= flash_make_addr (info
, 0, FLASH_OFFSET_INTEL_PROTECTION
);
813 flash_write_cmd (info
, 0, 0, FLASH_CMD_READ_ID
);
814 memcpy (buffer
, src
+ offset
, len
);
815 flash_write_cmd (info
, 0, 0, info
->cmd_reset
);
820 int flash_status_check (flash_info_t
* info
, flash_sect_t sector
,
821 uint64_t tout
, char *prompt
)
823 return info
->cfi_cmd_set
->flash_status_check(info
, sector
, tout
, prompt
);
827 * wait for XSR.7 to be set. Time out with an error if it does not.
828 * This routine does not set the flash to read-array mode.
830 int flash_generic_status_check (flash_info_t
* info
, flash_sect_t sector
,
831 uint64_t tout
, char *prompt
)
837 /* Wait for command completion */
838 start
= get_time_ns();
839 while (info
->cfi_cmd_set
->flash_is_busy (info
, sector
)) {
840 if (is_timeout(start
, tout
)) {
841 printf ("Flash %s timeout at address %lx data %lx\n",
842 prompt
, info
->start
[sector
],
843 flash_read_long (info
, sector
, 0));
844 flash_write_cmd (info
, sector
, 0, info
->cmd_reset
);
847 udelay (1); /* also triggers watchdog */
853 * make a proper sized command based on the port and chip widths
855 void flash_make_cmd (flash_info_t
* info
, uchar cmd
, void *cmdbuf
)
858 uchar
*cp
= (uchar
*) cmdbuf
;
860 #if defined(__LITTLE_ENDIAN)
861 for (i
= info
->portwidth
; i
> 0; i
--)
863 for (i
= 1; i
<= info
->portwidth
; i
++)
865 *cp
++ = (i
& (info
->chipwidth
- 1)) ? '\0' : cmd
;
869 * Write a proper sized command to the correct address
871 void flash_write_cmd (flash_info_t
* info
, flash_sect_t sect
, uint offset
, uchar cmd
)
877 addr
= flash_make_addr (info
, sect
, offset
);
878 flash_make_cmd (info
, cmd
, &cword
);
879 flash_write_word(info
, cword
, addr
);
882 int flash_isequal (flash_info_t
* info
, flash_sect_t sect
, uint offset
, uchar cmd
)
888 cptr
.cp
= flash_make_addr (info
, sect
, offset
);
889 flash_make_cmd (info
, cmd
, &cword
);
891 debug ("is= cmd %x(%c) addr %p ", cmd
, cmd
, cptr
.cp
);
892 if (bankwidth_is_1(info
)) {
893 debug ("is= %x %x\n", cptr
.cp
[0], cword
.c
);
894 retval
= (cptr
.cp
[0] == cword
.c
);
895 } else if (bankwidth_is_2(info
)) {
896 debug ("is= %4.4x %4.4x\n", cptr
.wp
[0], cword
.w
);
897 retval
= (cptr
.wp
[0] == cword
.w
);
898 } else if (bankwidth_is_4(info
)) {
899 debug ("is= %8.8lx %8.8lx\n", cptr
.lp
[0], cword
.l
);
900 retval
= (cptr
.lp
[0] == cword
.l
);
901 } else if (bankwidth_is_8(info
)) {
907 print_longlong (str1
, cptr
.llp
[0]);
908 print_longlong (str2
, cword
.ll
);
909 debug ("is= %s %s\n", str1
, str2
);
912 retval
= (cptr
.llp
[0] == cword
.ll
);
919 int flash_isset (flash_info_t
* info
, flash_sect_t sect
, uint offset
, uchar cmd
)
925 cptr
.cp
= flash_make_addr (info
, sect
, offset
);
926 flash_make_cmd (info
, cmd
, &cword
);
927 if (bankwidth_is_1(info
)) {
928 retval
= ((cptr
.cp
[0] & cword
.c
) == cword
.c
);
929 } else if (bankwidth_is_2(info
)) {
930 retval
= ((cptr
.wp
[0] & cword
.w
) == cword
.w
);
931 } else if (bankwidth_is_4(info
)) {
932 retval
= ((cptr
.lp
[0] & cword
.l
) == cword
.l
);
933 } else if (bankwidth_is_8(info
)) {
934 retval
= ((cptr
.llp
[0] & cword
.ll
) == cword
.ll
);
941 struct file_operations cfi_ops
= {
944 .lseek
= dev_lseek_default
,
946 .protect
= cfi_protect
,
947 .memmap
= generic_memmap_ro
,
950 static int cfi_probe (struct device_d
*dev
)
952 unsigned long size
= 0;
953 flash_info_t
*info
= xzalloc(sizeof(flash_info_t
));
955 dev
->priv
= (void *)info
;
957 printf("cfi_probe: %s base: 0x%08x size: 0x%08x\n", dev
->name
, dev
->map_base
, dev
->size
);
959 /* Init: no FLASHes known */
960 info
->flash_id
= FLASH_UNKNOWN
;
961 size
+= info
->size
= flash_get_size(info
, dev
->map_base
);
963 if (dev
->size
== 0) {
964 printf("cfi_probe: size : 0x%08x\n", info
->size
);
965 dev
->size
= info
->size
;
968 if (info
->flash_id
== FLASH_UNKNOWN
) {
969 printf ("## Unknown FLASH on Bank at 0x%08x - Size = 0x%08lx = %ld MB\n",
970 dev
->map_base
, info
->size
, info
->size
<< 20);
974 info
->cdev
.name
= asprintf("nor%d", dev
->id
);
975 info
->cdev
.size
= info
->size
;
976 info
->cdev
.dev
= dev
;
977 info
->cdev
.ops
= &cfi_ops
;
978 info
->cdev
.priv
= info
;
979 devfs_create(&info
->cdev
);
984 static struct driver_d cfi_driver
= {
990 static int cfi_init(void)
992 return register_driver(&cfi_driver
);
995 device_initcall(cfi_init
);