3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 /* environment.h defines the various CONFIG_ENV_... values in terms
27 * of whichever ones are given in the configuration file.
29 #include <environment.h>
31 flash_info_t flash_info
[CONFIG_SYS_MAX_FLASH_BANKS
]; /* info for FLASH chips */
33 /* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it
34 * has nothing to do with the flash chip being 8-bit or 16-bit.
36 #ifdef CONFIG_FLASH_16BIT
37 typedef unsigned short FLASH_PORT_WIDTH
;
38 typedef volatile unsigned short FLASH_PORT_WIDTHV
;
40 #define FLASH_ID_MASK 0xFFFF
42 typedef unsigned long FLASH_PORT_WIDTH
;
43 typedef volatile unsigned long FLASH_PORT_WIDTHV
;
45 #define FLASH_ID_MASK 0xFFFFFFFF
48 #define FPW FLASH_PORT_WIDTH
49 #define FPWV FLASH_PORT_WIDTHV
51 #define ORMASK(size) ((-size) & OR_AM_MSK)
53 /*-----------------------------------------------------------------------
56 static ulong
flash_get_size (FPWV
* addr
, flash_info_t
* info
);
57 static void flash_reset (flash_info_t
* info
);
58 static int write_word_intel (flash_info_t
* info
, FPWV
* dest
, FPW data
);
59 static int write_word_amd (flash_info_t
* info
, FPWV
* dest
, FPW data
);
60 static void flash_get_offsets (ulong base
, flash_info_t
* info
);
62 #ifdef CONFIG_SYS_FLASH_PROTECTION
63 static void flash_sync_real_protect (flash_info_t
* info
);
66 /*-----------------------------------------------------------------------
69 * sets up flash_info and returns size of FLASH (bytes)
71 unsigned long flash_init (void)
76 /* Init: no FLASHes known */
77 for (i
= 0; i
< CONFIG_SYS_MAX_FLASH_BANKS
; ++i
) {
78 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
81 size_b
= flash_get_size ((FPW
*) CONFIG_SYS_FLASH_BASE
, &flash_info
[0]);
83 flash_info
[0].size
= size_b
;
85 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
86 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx\n",
90 /* Do this again (was done already in flast_get_size), just
91 * in case we move it when remap the FLASH.
93 flash_get_offsets (CONFIG_SYS_FLASH_BASE
, &flash_info
[0]);
95 #ifdef CONFIG_SYS_FLASH_PROTECTION
96 /* read the hardware protection status (if any) into the
97 * protection array in flash_info.
99 flash_sync_real_protect (&flash_info
[0]);
102 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
103 /* monitor protection ON by default */
104 flash_protect (FLAG_PROTECT_SET
,
105 CONFIG_SYS_MONITOR_BASE
,
106 CONFIG_SYS_MONITOR_BASE
+ monitor_flash_len
- 1,
110 #ifdef CONFIG_ENV_ADDR
111 flash_protect (FLAG_PROTECT_SET
,
113 CONFIG_ENV_ADDR
+ CONFIG_ENV_SECT_SIZE
- 1, &flash_info
[0]);
116 #ifdef CONFIG_ENV_ADDR_REDUND
117 flash_protect (FLAG_PROTECT_SET
,
118 CONFIG_ENV_ADDR_REDUND
,
119 CONFIG_ENV_ADDR_REDUND
+ CONFIG_ENV_SECT_SIZE
- 1,
126 /*-----------------------------------------------------------------------
128 static void flash_reset (flash_info_t
* info
)
130 FPWV
*base
= (FPWV
*) (info
->start
[0]);
132 /* Put FLASH back in read mode */
133 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
134 *base
= (FPW
) 0x00FF00FF; /* Intel Read Mode */
135 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
)
136 *base
= (FPW
) 0x00F000F0; /* AMD Read Mode */
139 /*-----------------------------------------------------------------------
141 static void flash_get_offsets (ulong base
, flash_info_t
* info
)
145 /* set up sector start address table */
146 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
147 && (info
->flash_id
& FLASH_BTYPE
)) {
148 int bootsect_size
; /* number of bytes/boot sector */
149 int sect_size
; /* number of bytes/regular sector */
151 bootsect_size
= 0x00002000 * (sizeof (FPW
) / 2);
152 sect_size
= 0x00010000 * (sizeof (FPW
) / 2);
154 /* set sector offsets for bottom boot block type */
155 for (i
= 0; i
< 8; ++i
) {
156 info
->start
[i
] = base
+ (i
* bootsect_size
);
158 for (i
= 8; i
< info
->sector_count
; i
++) {
159 info
->start
[i
] = base
+ ((i
- 7) * sect_size
);
161 } else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
162 && (info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM640U
) {
164 int sect_size
; /* number of bytes/sector */
166 sect_size
= 0x00010000 * (sizeof (FPW
) / 2);
168 /* set up sector start address table (uniform sector type) */
169 for (i
= 0; i
< info
->sector_count
; i
++)
170 info
->start
[i
] = base
+ (i
* sect_size
);
171 } else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
172 && (info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM800T
) {
174 int sect_size
; /* number of bytes/sector */
176 sect_size
= 0x00010000 * (sizeof (FPW
) / 2);
178 /* set up sector start address table (top boot sector type) */
179 for (i
= 0; i
< info
->sector_count
- 3; i
++)
180 info
->start
[i
] = base
+ (i
* sect_size
);
181 i
= info
->sector_count
- 1;
183 base
+ (info
->size
- 0x00004000) * (sizeof (FPW
) / 2);
185 base
+ (info
->size
- 0x00006000) * (sizeof (FPW
) / 2);
187 base
+ (info
->size
- 0x00008000) * (sizeof (FPW
) / 2);
191 /*-----------------------------------------------------------------------
194 void flash_print_info (flash_info_t
* info
)
200 uchar botbootletter
[] = "B";
201 uchar topbootletter
[] = "T";
202 uchar botboottype
[] = "bottom boot sector";
203 uchar topboottype
[] = "top boot sector";
205 if (info
->flash_id
== FLASH_UNKNOWN
) {
206 printf ("missing or unknown FLASH type\n");
210 switch (info
->flash_id
& FLASH_VENDMASK
) {
215 printf ("BRIGHT MICRO ");
226 case FLASH_MAN_INTEL
:
230 printf ("Unknown Vendor ");
234 /* check for top or bottom boot, if it applies */
235 if (info
->flash_id
& FLASH_BTYPE
) {
236 boottype
= botboottype
;
237 bootletter
= botbootletter
;
239 boottype
= topboottype
;
240 bootletter
= topbootletter
;
243 switch (info
->flash_id
& FLASH_TYPEMASK
) {
245 fmt
= "29LV800B%s (8 Mbit, %s)\n";
248 fmt
= "29LV641D (64 Mbit, uniform sectors)\n";
250 case FLASH_28F800C3B
:
251 case FLASH_28F800C3T
:
252 fmt
= "28F800C3%s (8 Mbit, %s)\n";
254 case FLASH_INTEL800B
:
255 case FLASH_INTEL800T
:
256 fmt
= "28F800B3%s (8 Mbit, %s)\n";
258 case FLASH_28F160C3B
:
259 case FLASH_28F160C3T
:
260 fmt
= "28F160C3%s (16 Mbit, %s)\n";
262 case FLASH_INTEL160B
:
263 case FLASH_INTEL160T
:
264 fmt
= "28F160B3%s (16 Mbit, %s)\n";
266 case FLASH_28F320C3B
:
267 case FLASH_28F320C3T
:
268 fmt
= "28F320C3%s (32 Mbit, %s)\n";
270 case FLASH_INTEL320B
:
271 case FLASH_INTEL320T
:
272 fmt
= "28F320B3%s (32 Mbit, %s)\n";
274 case FLASH_28F640C3B
:
275 case FLASH_28F640C3T
:
276 fmt
= "28F640C3%s (64 Mbit, %s)\n";
278 case FLASH_INTEL640B
:
279 case FLASH_INTEL640T
:
280 fmt
= "28F640B3%s (64 Mbit, %s)\n";
283 fmt
= "Unknown Chip Type\n";
287 printf (fmt
, bootletter
, boottype
);
289 printf (" Size: %ld MB in %d Sectors\n",
290 info
->size
>> 20, info
->sector_count
);
292 printf (" Sector Start Addresses:");
294 for (i
= 0; i
< info
->sector_count
; ++i
) {
299 printf (" %08lX%s", info
->start
[i
],
300 info
->protect
[i
] ? " (RO)" : " ");
306 /*-----------------------------------------------------------------------
310 * The following code cannot be run from FLASH!
313 ulong
flash_get_size (FPWV
* addr
, flash_info_t
* info
)
315 /* Write auto select command: read Manufacturer ID */
317 /* Write auto select command sequence and test FLASH answer */
318 addr
[0x0555] = (FPW
) 0x00AA00AA; /* for AMD, Intel ignores this */
319 addr
[0x02AA] = (FPW
) 0x00550055; /* for AMD, Intel ignores this */
320 addr
[0x0555] = (FPW
) 0x00900090; /* selects Intel or AMD */
322 /* The manufacturer codes are only 1 byte, so just use 1 byte.
323 * This works for any bus width and any FLASH device width.
325 switch (addr
[0] & 0xff) {
327 case (uchar
) AMD_MANUFACT
:
328 info
->flash_id
= FLASH_MAN_AMD
;
331 case (uchar
) INTEL_MANUFACT
:
332 info
->flash_id
= FLASH_MAN_INTEL
;
336 info
->flash_id
= FLASH_UNKNOWN
;
337 info
->sector_count
= 0;
342 /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
343 if (info
->flash_id
!= FLASH_UNKNOWN
)
346 case (FPW
) AMD_ID_LV800T
:
347 info
->flash_id
+= FLASH_AM800T
;
348 info
->sector_count
= 19;
349 info
->size
= 0x00100000 * (sizeof (FPW
) / 2);
350 break; /* => 1 or 2 MiB */
352 case (FPW
) AMD_ID_LV640U
: /* 29LV640 and 29LV641 have same ID */
353 info
->flash_id
+= FLASH_AM640U
;
354 info
->sector_count
= 128;
355 info
->size
= 0x00800000 * (sizeof (FPW
) / 2);
356 break; /* => 8 or 16 MB */
358 case (FPW
) INTEL_ID_28F800C3B
:
359 info
->flash_id
+= FLASH_28F800C3B
;
360 info
->sector_count
= 23;
361 info
->size
= 0x00100000 * (sizeof (FPW
) / 2);
362 break; /* => 1 or 2 MB */
364 case (FPW
) INTEL_ID_28F800B3B
:
365 info
->flash_id
+= FLASH_INTEL800B
;
366 info
->sector_count
= 23;
367 info
->size
= 0x00100000 * (sizeof (FPW
) / 2);
368 break; /* => 1 or 2 MB */
370 case (FPW
) INTEL_ID_28F160C3B
:
371 info
->flash_id
+= FLASH_28F160C3B
;
372 info
->sector_count
= 39;
373 info
->size
= 0x00200000 * (sizeof (FPW
) / 2);
374 break; /* => 2 or 4 MB */
376 case (FPW
) INTEL_ID_28F160B3B
:
377 info
->flash_id
+= FLASH_INTEL160B
;
378 info
->sector_count
= 39;
379 info
->size
= 0x00200000 * (sizeof (FPW
) / 2);
380 break; /* => 2 or 4 MB */
382 case (FPW
) INTEL_ID_28F320C3B
:
383 info
->flash_id
+= FLASH_28F320C3B
;
384 info
->sector_count
= 71;
385 info
->size
= 0x00400000 * (sizeof (FPW
) / 2);
386 break; /* => 4 or 8 MB */
388 case (FPW
) INTEL_ID_28F320B3B
:
389 info
->flash_id
+= FLASH_INTEL320B
;
390 info
->sector_count
= 71;
391 info
->size
= 0x00400000 * (sizeof (FPW
) / 2);
392 break; /* => 4 or 8 MB */
394 case (FPW
) INTEL_ID_28F640C3B
:
395 info
->flash_id
+= FLASH_28F640C3B
;
396 info
->sector_count
= 135;
397 info
->size
= 0x00800000 * (sizeof (FPW
) / 2);
398 break; /* => 8 or 16 MB */
400 case (FPW
) INTEL_ID_28F640B3B
:
401 info
->flash_id
+= FLASH_INTEL640B
;
402 info
->sector_count
= 135;
403 info
->size
= 0x00800000 * (sizeof (FPW
) / 2);
404 break; /* => 8 or 16 MB */
407 info
->flash_id
= FLASH_UNKNOWN
;
408 info
->sector_count
= 0;
410 return (0); /* => no or unknown flash */
413 flash_get_offsets ((ulong
) addr
, info
);
415 /* Put FLASH back in read mode */
421 #ifdef CONFIG_SYS_FLASH_PROTECTION
422 /*-----------------------------------------------------------------------
425 static void flash_sync_real_protect (flash_info_t
* info
)
427 FPWV
*addr
= (FPWV
*) (info
->start
[0]);
431 switch (info
->flash_id
& FLASH_TYPEMASK
) {
432 case FLASH_28F800C3B
:
433 case FLASH_28F800C3T
:
434 case FLASH_28F160C3B
:
435 case FLASH_28F160C3T
:
436 case FLASH_28F320C3B
:
437 case FLASH_28F320C3T
:
438 case FLASH_28F640C3B
:
439 case FLASH_28F640C3T
:
440 /* check for protected sectors */
441 *addr
= (FPW
) 0x00900090;
442 for (i
= 0; i
< info
->sector_count
; i
++) {
443 /* read sector protection at sector address, (A7 .. A0) = 0x02.
444 * D0 = 1 for each device if protected.
445 * If at least one device is protected the sector is marked
446 * protected, but mixed protected and unprotected devices
447 * within a sector should never happen.
449 sect
= (FPWV
*) (info
->start
[i
]);
451 (sect
[2] & (FPW
) (0x00010001)) ? 1 : 0;
454 /* Put FLASH back in read mode */
461 /* no hardware protect that we support */
467 /*-----------------------------------------------------------------------
470 int flash_erase (flash_info_t
* info
, int s_first
, int s_last
)
473 int flag
, prot
, sect
;
474 int intel
= (info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
;
478 if ((s_first
< 0) || (s_first
> s_last
)) {
479 if (info
->flash_id
== FLASH_UNKNOWN
) {
480 printf ("- missing\n");
482 printf ("- no sectors to erase\n");
487 switch (info
->flash_id
& FLASH_TYPEMASK
) {
488 case FLASH_INTEL800B
:
489 case FLASH_INTEL160B
:
490 case FLASH_INTEL320B
:
491 case FLASH_INTEL640B
:
492 case FLASH_28F800C3B
:
493 case FLASH_28F160C3B
:
494 case FLASH_28F320C3B
:
495 case FLASH_28F640C3B
:
501 printf ("Can't erase unknown flash type %08lx - aborted\n",
507 for (sect
= s_first
; sect
<= s_last
; ++sect
) {
508 if (info
->protect
[sect
]) {
514 printf ("- Warning: %d protected sectors will not be erased!\n", prot
);
519 reset_timer_masked ();
521 /* Start erase on unprotected sectors */
522 for (sect
= s_first
; sect
<= s_last
&& rcode
== 0; sect
++) {
524 if (info
->protect
[sect
] != 0) /* protected, skip it */
527 /* Disable interrupts which might cause a timeout here */
528 flag
= disable_interrupts ();
530 reset_timer_masked ();
533 addr
= (FPWV
*) (info
->start
[sect
]);
535 *addr
= (FPW
) 0x00500050; /* clear status register */
536 *addr
= (FPW
) 0x00200020; /* erase setup */
537 *addr
= (FPW
) 0x00D000D0; /* erase confirm */
539 /* must be AMD style if not Intel */
540 FPWV
*base
; /* first address in bank */
542 base
= (FPWV
*) (info
->start
[0]);
543 base
[0x0555] = (FPW
) 0x00AA00AA; /* unlock */
544 base
[0x02AA] = (FPW
) 0x00550055; /* unlock */
545 base
[0x0555] = (FPW
) 0x00800080; /* erase mode */
546 base
[0x0555] = (FPW
) 0x00AA00AA; /* unlock */
547 base
[0x02AA] = (FPW
) 0x00550055; /* unlock */
548 *addr
= (FPW
) 0x00300030; /* erase sector */
551 /* re-enable interrupts if necessary */
553 enable_interrupts ();
555 /* wait at least 50us for AMD, 80us for Intel.
560 while ((*addr
& (FPW
) 0x00800080) != (FPW
) 0x00800080) {
562 get_timer_masked ()) > CONFIG_SYS_FLASH_ERASE_TOUT
) {
563 printf ("Timeout\n");
567 *addr
= (FPW
) 0x00B000B0;
570 flash_reset (info
); /* reset to read mode */
571 rcode
= 1; /* failed */
575 /* show that we're waiting */
576 if ((now
- last
) > 1 * CONFIG_SYS_HZ
) { /* every second */
582 flash_reset (info
); /* reset to read mode */
589 /*-----------------------------------------------------------------------
590 * Copy memory to flash, returns:
593 * 2 - Flash not erased
595 int write_buff (flash_info_t
* info
, uchar
* src
, ulong addr
, ulong cnt
)
597 FPW data
= 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
598 int bytes
; /* number of bytes to program in current word */
599 int left
; /* number of bytes left to program */
602 for (left
= cnt
, res
= 0;
603 left
> 0 && res
== 0;
604 addr
+= sizeof (data
), left
-= sizeof (data
) - bytes
) {
606 bytes
= addr
& (sizeof (data
) - 1);
607 addr
&= ~(sizeof (data
) - 1);
609 /* combine source and destination data so can program
610 * an entire word of 16 or 32 bits
612 #ifdef CONFIG_SYS_LITTLE_ENDIAN
613 for (i
= 0; i
< sizeof (data
); i
++) {
615 if (i
< bytes
|| i
- bytes
>= left
)
616 data
+= (*((uchar
*) addr
+ i
)) << 24;
618 data
+= (*src
++) << 24;
621 for (i
= 0; i
< sizeof (data
); i
++) {
623 if (i
< bytes
|| i
- bytes
>= left
)
624 data
+= *((uchar
*) addr
+ i
);
630 /* write one word to the flash */
631 switch (info
->flash_id
& FLASH_VENDMASK
) {
633 res
= write_word_amd (info
, (FPWV
*) addr
, data
);
635 case FLASH_MAN_INTEL
:
636 res
= write_word_intel (info
, (FPWV
*) addr
, data
);
639 /* unknown flash type, error! */
640 printf ("missing or unknown FLASH type\n");
641 res
= 1; /* not really a timeout, but gives error */
649 /*-----------------------------------------------------------------------
650 * Write a word to Flash for AMD FLASH
651 * A word is 16 or 32 bits, whichever the bus width of the flash bank
652 * (not an individual chip) is.
657 * 2 - Flash not erased
659 static int write_word_amd (flash_info_t
* info
, FPWV
* dest
, FPW data
)
662 int res
= 0; /* result, assume success */
663 FPWV
*base
; /* first address in flash bank */
665 /* Check if Flash is (sufficiently) erased */
666 if ((*dest
& data
) != data
) {
671 base
= (FPWV
*) (info
->start
[0]);
673 /* Disable interrupts which might cause a timeout here */
674 flag
= disable_interrupts ();
676 base
[0x0555] = (FPW
) 0x00AA00AA; /* unlock */
677 base
[0x02AA] = (FPW
) 0x00550055; /* unlock */
678 base
[0x0555] = (FPW
) 0x00A000A0; /* selects program mode */
680 *dest
= data
; /* start programming the data */
682 /* re-enable interrupts if necessary */
684 enable_interrupts ();
686 reset_timer_masked ();
688 /* data polling for D7 */
690 && (*dest
& (FPW
) 0x00800080) != (data
& (FPW
) 0x00800080)) {
691 if (get_timer_masked () > CONFIG_SYS_FLASH_WRITE_TOUT
) {
692 *dest
= (FPW
) 0x00F000F0; /* reset bank */
700 /*-----------------------------------------------------------------------
701 * Write a word to Flash for Intel FLASH
702 * A word is 16 or 32 bits, whichever the bus width of the flash bank
703 * (not an individual chip) is.
708 * 2 - Flash not erased
710 static int write_word_intel (flash_info_t
* info
, FPWV
* dest
, FPW data
)
713 int res
= 0; /* result, assume success */
715 /* Check if Flash is (sufficiently) erased */
716 if ((*dest
& data
) != data
) {
720 /* Disable interrupts which might cause a timeout here */
721 flag
= disable_interrupts ();
723 *dest
= (FPW
) 0x00500050; /* clear status register */
724 *dest
= (FPW
) 0x00FF00FF; /* make sure in read mode */
725 *dest
= (FPW
) 0x00400040; /* program setup */
727 *dest
= data
; /* start programming the data */
729 /* re-enable interrupts if necessary */
731 enable_interrupts ();
733 reset_timer_masked ();
735 while (res
== 0 && (*dest
& (FPW
) 0x00800080) != (FPW
) 0x00800080) {
736 if (get_timer_masked () > CONFIG_SYS_FLASH_WRITE_TOUT
) {
737 *dest
= (FPW
) 0x00B000B0; /* Suspend program */
742 if (res
== 0 && (*dest
& (FPW
) 0x00100010))
743 res
= 1; /* write failed, time out error is close enough */
745 *dest
= (FPW
) 0x00500050; /* clear status register */
746 *dest
= (FPW
) 0x00FF00FF; /* make sure in read mode */
751 #ifdef CONFIG_SYS_FLASH_PROTECTION
752 /*-----------------------------------------------------------------------
754 int flash_real_protect (flash_info_t
* info
, long sector
, int prot
)
756 int rcode
= 0; /* assume success */
757 FPWV
*addr
; /* address of sector */
760 addr
= (FPWV
*) (info
->start
[sector
]);
762 switch (info
->flash_id
& FLASH_TYPEMASK
) {
763 case FLASH_28F800C3B
:
764 case FLASH_28F800C3T
:
765 case FLASH_28F160C3B
:
766 case FLASH_28F160C3T
:
767 case FLASH_28F320C3B
:
768 case FLASH_28F320C3T
:
769 case FLASH_28F640C3B
:
770 case FLASH_28F640C3T
:
771 flash_reset (info
); /* make sure in read mode */
772 *addr
= (FPW
) 0x00600060L
; /* lock command setup */
774 *addr
= (FPW
) 0x00010001L
; /* lock sector */
776 *addr
= (FPW
) 0x00D000D0L
; /* unlock sector */
777 flash_reset (info
); /* reset to read mode */
779 /* now see if it really is locked/unlocked as requested */
780 *addr
= (FPW
) 0x00900090;
781 /* read sector protection at sector address, (A7 .. A0) = 0x02.
782 * D0 = 1 for each device if protected.
783 * If at least one device is protected the sector is marked
784 * protected, but return failure. Mixed protected and
785 * unprotected devices within a sector should never happen.
787 value
= addr
[2] & (FPW
) 0x00010001;
789 info
->protect
[sector
] = 0;
790 else if (value
== (FPW
) 0x00010001)
791 info
->protect
[sector
] = 1;
793 /* error, mixed protected and unprotected */
795 info
->protect
[sector
] = 1;
797 if (info
->protect
[sector
] != prot
)
798 rcode
= 1; /* failed to protect/unprotect as requested */
800 /* reload all protection bits from hardware for now */
801 flash_sync_real_protect (info
);
807 /* no hardware protect that we support */
808 info
->protect
[sector
] = prot
;