]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/sixnet/flash.c
61d758085c238f3309ad1e0f92d2e5c0325f0d37
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 CFG_ENV_... values in terms
27 * of whichever ones are given in the configuration file.
29 #include <environment.h>
31 flash_info_t flash_info
[CFG_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
;
39 #define FLASH_ID_MASK 0xFFFF
41 typedef unsigned long FLASH_PORT_WIDTH
;
42 typedef volatile unsigned long FLASH_PORT_WIDTHV
;
43 #define FLASH_ID_MASK 0xFFFFFFFF
46 #define FPW FLASH_PORT_WIDTH
47 #define FPWV FLASH_PORT_WIDTHV
49 #define ORMASK(size) ((-size) & OR_AM_MSK)
51 /*-----------------------------------------------------------------------
54 static ulong
flash_get_size(FPWV
*addr
, flash_info_t
*info
);
55 static void flash_reset(flash_info_t
*info
);
56 static int write_word_intel(flash_info_t
*info
, FPWV
*dest
, FPW data
);
57 static int write_word_amd(flash_info_t
*info
, FPWV
*dest
, FPW data
);
58 static void flash_get_offsets(ulong base
, flash_info_t
*info
);
59 #ifdef CFG_FLASH_PROTECTION
60 static void flash_sync_real_protect(flash_info_t
*info
);
63 /*-----------------------------------------------------------------------
66 * sets up flash_info and returns size of FLASH (bytes)
68 unsigned long flash_init (void)
70 volatile immap_t
*immap
= (immap_t
*)CFG_IMMR
;
71 volatile memctl8xx_t
*memctl
= &immap
->im_memctl
;
75 /* Init: no FLASHes known */
76 for (i
=0; i
< CFG_MAX_FLASH_BANKS
; ++i
) {
77 flash_info
[i
].flash_id
= FLASH_UNKNOWN
;
80 size_b
= flash_get_size((FPW
*)CFG_FLASH_BASE
, &flash_info
[0]);
82 flash_info
[0].size
= size_b
;
84 if (flash_info
[0].flash_id
== FLASH_UNKNOWN
) {
85 printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx\n",size_b
);
88 /* Remap FLASH according to real size, so only at proper address */
89 memctl
->memc_or0
= (memctl
->memc_or0
& ~OR_AM_MSK
) | ORMASK(size_b
);
91 /* Do this again (was done already in flast_get_size), just
92 * in case we move it when remap the FLASH.
94 flash_get_offsets (CFG_FLASH_BASE
, &flash_info
[0]);
96 #ifdef CFG_FLASH_PROTECTION
97 /* read the hardware protection status (if any) into the
98 * protection array in flash_info.
100 flash_sync_real_protect(&flash_info
[0]);
103 #if CFG_MONITOR_BASE >= CFG_FLASH_BASE
104 /* monitor protection ON by default */
105 flash_protect(FLAG_PROTECT_SET
,
107 CFG_MONITOR_BASE
+monitor_flash_len
-1,
112 flash_protect ( FLAG_PROTECT_SET
,
114 CFG_ENV_ADDR
+ CFG_ENV_SIZE
- 1, &flash_info
[0]);
117 #ifdef CFG_ENV_ADDR_REDUND
118 flash_protect ( FLAG_PROTECT_SET
,
120 CFG_ENV_ADDR_REDUND
+ CFG_ENV_SIZE_REDUND
- 1,
127 /*-----------------------------------------------------------------------
129 static void flash_reset(flash_info_t
*info
)
131 FPWV
*base
= (FPWV
*)(info
->start
[0]);
133 /* Put FLASH back in read mode */
134 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
135 *base
= (FPW
)0x00FF00FF; /* Intel Read Mode */
136 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
)
137 *base
= (FPW
)0x00F000F0; /* AMD Read Mode */
140 /*-----------------------------------------------------------------------
142 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
146 /* set up sector start address table */
147 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
148 && (info
->flash_id
& FLASH_BTYPE
)) {
149 int bootsect_size
; /* number of bytes/boot sector */
150 int sect_size
; /* number of bytes/regular sector */
152 bootsect_size
= 0x00002000 * (sizeof(FPW
)/2);
153 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
155 /* set sector offsets for bottom boot block type */
156 for (i
= 0; i
< 8; ++i
) {
157 info
->start
[i
] = base
+ (i
* bootsect_size
);
159 for (i
= 8; i
< info
->sector_count
; i
++) {
160 info
->start
[i
] = base
+ ((i
- 7) * sect_size
);
163 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
164 && (info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM640U
) {
166 int sect_size
; /* number of bytes/sector */
168 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
170 /* set up sector start address table (uniform sector type) */
171 for( i
= 0; i
< info
->sector_count
; i
++ )
172 info
->start
[i
] = base
+ (i
* sect_size
);
174 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
175 && (info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM800T
) {
177 int sect_size
; /* number of bytes/sector */
179 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
181 /* set up sector start address table (top boot sector type) */
182 for (i
= 0; i
< info
->sector_count
- 3; i
++)
183 info
->start
[i
] = base
+ (i
* sect_size
);
184 i
= info
->sector_count
- 1;
185 info
->start
[i
--] = base
+ (info
->size
- 0x00004000) * (sizeof(FPW
)/2);
186 info
->start
[i
--] = base
+ (info
->size
- 0x00006000) * (sizeof(FPW
)/2);
187 info
->start
[i
--] = 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
) {
211 case FLASH_MAN_AMD
: printf ("AMD "); break;
212 case FLASH_MAN_BM
: printf ("BRIGHT MICRO "); break;
213 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
214 case FLASH_MAN_SST
: printf ("SST "); break;
215 case FLASH_MAN_STM
: printf ("STM "); break;
216 case FLASH_MAN_INTEL
: printf ("INTEL "); break;
217 default: printf ("Unknown Vendor "); break;
220 /* check for top or bottom boot, if it applies */
221 if (info
->flash_id
& FLASH_BTYPE
) {
222 boottype
= botboottype
;
223 bootletter
= botbootletter
;
226 boottype
= topboottype
;
227 bootletter
= topbootletter
;
230 switch (info
->flash_id
& FLASH_TYPEMASK
) {
232 fmt
= "29LV800B%s (8 Mbit, %s)\n";
235 fmt
= "29LV641D (64 Mbit, uniform sectors)\n";
237 case FLASH_28F800C3B
:
238 case FLASH_28F800C3T
:
239 fmt
= "28F800C3%s (8 Mbit, %s)\n";
241 case FLASH_INTEL800B
:
242 case FLASH_INTEL800T
:
243 fmt
= "28F800B3%s (8 Mbit, %s)\n";
245 case FLASH_28F160C3B
:
246 case FLASH_28F160C3T
:
247 fmt
= "28F160C3%s (16 Mbit, %s)\n";
249 case FLASH_INTEL160B
:
250 case FLASH_INTEL160T
:
251 fmt
= "28F160B3%s (16 Mbit, %s)\n";
253 case FLASH_28F320C3B
:
254 case FLASH_28F320C3T
:
255 fmt
= "28F320C3%s (32 Mbit, %s)\n";
257 case FLASH_INTEL320B
:
258 case FLASH_INTEL320T
:
259 fmt
= "28F320B3%s (32 Mbit, %s)\n";
261 case FLASH_28F640C3B
:
262 case FLASH_28F640C3T
:
263 fmt
= "28F640C3%s (64 Mbit, %s)\n";
265 case FLASH_INTEL640B
:
266 case FLASH_INTEL640T
:
267 fmt
= "28F640B3%s (64 Mbit, %s)\n";
270 fmt
= "Unknown Chip Type\n";
274 printf (fmt
, bootletter
, boottype
);
276 printf (" Size: %ld MB in %d Sectors\n",
280 printf (" Sector Start Addresses:");
282 for (i
=0; i
<info
->sector_count
; ++i
) {
287 printf (" %08lX%s", info
->start
[i
],
288 info
->protect
[i
] ? " (RO)" : " ");
294 /*-----------------------------------------------------------------------
298 * The following code cannot be run from FLASH!
301 ulong
flash_get_size (FPWV
*addr
, flash_info_t
*info
)
303 /* Write auto select command: read Manufacturer ID */
305 /* Write auto select command sequence and test FLASH answer */
306 addr
[0x0555] = (FPW
)0x00AA00AA; /* for AMD, Intel ignores this */
307 addr
[0x02AA] = (FPW
)0x00550055; /* for AMD, Intel ignores this */
308 addr
[0x0555] = (FPW
)0x00900090; /* selects Intel or AMD */
310 /* The manufacturer codes are only 1 byte, so just use 1 byte.
311 * This works for any bus width and any FLASH device width.
313 switch (addr
[0] & 0xff) {
315 case (uchar
)AMD_MANUFACT
:
316 info
->flash_id
= FLASH_MAN_AMD
;
319 case (uchar
)INTEL_MANUFACT
:
320 info
->flash_id
= FLASH_MAN_INTEL
;
324 info
->flash_id
= FLASH_UNKNOWN
;
325 info
->sector_count
= 0;
330 /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
331 if (info
->flash_id
!= FLASH_UNKNOWN
) switch (addr
[1]) {
333 case (FPW
)AMD_ID_LV800T
:
334 info
->flash_id
+= FLASH_AM800T
;
335 info
->sector_count
= 19;
336 info
->size
= 0x00100000 * (sizeof(FPW
)/2);
337 break; /* => 1 or 2 MiB */
339 case (FPW
)AMD_ID_LV640U
: /* 29LV640 and 29LV641 have same ID */
340 info
->flash_id
+= FLASH_AM640U
;
341 info
->sector_count
= 128;
342 info
->size
= 0x00800000 * (sizeof(FPW
)/2);
343 break; /* => 8 or 16 MB */
345 case (FPW
)INTEL_ID_28F800C3B
:
346 info
->flash_id
+= FLASH_28F800C3B
;
347 info
->sector_count
= 23;
348 info
->size
= 0x00100000 * (sizeof(FPW
)/2);
349 break; /* => 1 or 2 MB */
351 case (FPW
)INTEL_ID_28F800B3B
:
352 info
->flash_id
+= FLASH_INTEL800B
;
353 info
->sector_count
= 23;
354 info
->size
= 0x00100000 * (sizeof(FPW
)/2);
355 break; /* => 1 or 2 MB */
357 case (FPW
)INTEL_ID_28F160C3B
:
358 info
->flash_id
+= FLASH_28F160C3B
;
359 info
->sector_count
= 39;
360 info
->size
= 0x00200000 * (sizeof(FPW
)/2);
361 break; /* => 2 or 4 MB */
363 case (FPW
)INTEL_ID_28F160B3B
:
364 info
->flash_id
+= FLASH_INTEL160B
;
365 info
->sector_count
= 39;
366 info
->size
= 0x00200000 * (sizeof(FPW
)/2);
367 break; /* => 2 or 4 MB */
369 case (FPW
)INTEL_ID_28F320C3B
:
370 info
->flash_id
+= FLASH_28F320C3B
;
371 info
->sector_count
= 71;
372 info
->size
= 0x00400000 * (sizeof(FPW
)/2);
373 break; /* => 4 or 8 MB */
375 case (FPW
)INTEL_ID_28F320B3B
:
376 info
->flash_id
+= FLASH_INTEL320B
;
377 info
->sector_count
= 71;
378 info
->size
= 0x00400000 * (sizeof(FPW
)/2);
379 break; /* => 4 or 8 MB */
381 case (FPW
)INTEL_ID_28F640C3B
:
382 info
->flash_id
+= FLASH_28F640C3B
;
383 info
->sector_count
= 135;
384 info
->size
= 0x00800000 * (sizeof(FPW
)/2);
385 break; /* => 8 or 16 MB */
387 case (FPW
)INTEL_ID_28F640B3B
:
388 info
->flash_id
+= FLASH_INTEL640B
;
389 info
->sector_count
= 135;
390 info
->size
= 0x00800000 * (sizeof(FPW
)/2);
391 break; /* => 8 or 16 MB */
394 info
->flash_id
= FLASH_UNKNOWN
;
395 info
->sector_count
= 0;
397 return (0); /* => no or unknown flash */
400 flash_get_offsets((ulong
)addr
, info
);
402 /* Put FLASH back in read mode */
408 #ifdef CFG_FLASH_PROTECTION
409 /*-----------------------------------------------------------------------
412 static void flash_sync_real_protect(flash_info_t
*info
)
414 FPWV
*addr
= (FPWV
*)(info
->start
[0]);
418 switch (info
->flash_id
& FLASH_TYPEMASK
) {
419 case FLASH_28F800C3B
:
420 case FLASH_28F800C3T
:
421 case FLASH_28F160C3B
:
422 case FLASH_28F160C3T
:
423 case FLASH_28F320C3B
:
424 case FLASH_28F320C3T
:
425 case FLASH_28F640C3B
:
426 case FLASH_28F640C3T
:
427 /* check for protected sectors */
428 *addr
= (FPW
)0x00900090;
429 for (i
= 0; i
< info
->sector_count
; i
++) {
430 /* read sector protection at sector address, (A7 .. A0) = 0x02.
431 * D0 = 1 for each device if protected.
432 * If at least one device is protected the sector is marked
433 * protected, but mixed protected and unprotected devices
434 * within a sector should never happen.
436 sect
= (FPWV
*)(info
->start
[i
]);
437 info
->protect
[i
] = (sect
[2] & (FPW
)(0x00010001)) ? 1 : 0;
440 /* Put FLASH back in read mode */
447 /* no hardware protect that we support */
453 /*-----------------------------------------------------------------------
456 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
459 int flag
, prot
, sect
;
460 int intel
= (info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
;
461 ulong start
, now
, last
;
464 if ((s_first
< 0) || (s_first
> s_last
)) {
465 if (info
->flash_id
== FLASH_UNKNOWN
) {
466 printf ("- missing\n");
468 printf ("- no sectors to erase\n");
473 switch (info
->flash_id
& FLASH_TYPEMASK
) {
474 case FLASH_INTEL800B
:
475 case FLASH_INTEL160B
:
476 case FLASH_INTEL320B
:
477 case FLASH_INTEL640B
:
478 case FLASH_28F800C3B
:
479 case FLASH_28F160C3B
:
480 case FLASH_28F320C3B
:
481 case FLASH_28F640C3B
:
487 printf ("Can't erase unknown flash type %08lx - aborted\n",
493 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
494 if (info
->protect
[sect
]) {
500 printf ("- Warning: %d protected sectors will not be erased!\n",
506 start
= get_timer(0);
509 /* Start erase on unprotected sectors */
510 for (sect
= s_first
; sect
<=s_last
&& rcode
== 0; sect
++) {
512 if (info
->protect
[sect
] != 0) /* protected, skip it */
515 /* Disable interrupts which might cause a timeout here */
516 flag
= disable_interrupts();
518 addr
= (FPWV
*)(info
->start
[sect
]);
520 *addr
= (FPW
)0x00500050; /* clear status register */
521 *addr
= (FPW
)0x00200020; /* erase setup */
522 *addr
= (FPW
)0x00D000D0; /* erase confirm */
525 /* must be AMD style if not Intel */
526 FPWV
*base
; /* first address in bank */
528 base
= (FPWV
*)(info
->start
[0]);
529 base
[0x0555] = (FPW
)0x00AA00AA; /* unlock */
530 base
[0x02AA] = (FPW
)0x00550055; /* unlock */
531 base
[0x0555] = (FPW
)0x00800080; /* erase mode */
532 base
[0x0555] = (FPW
)0x00AA00AA; /* unlock */
533 base
[0x02AA] = (FPW
)0x00550055; /* unlock */
534 *addr
= (FPW
)0x00300030; /* erase sector */
537 /* re-enable interrupts if necessary */
541 /* wait at least 50us for AMD, 80us for Intel.
546 while ((*addr
& (FPW
)0x00800080) != (FPW
)0x00800080) {
547 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
548 printf ("Timeout\n");
552 *addr
= (FPW
)0x00B000B0;
555 flash_reset(info
); /* reset to read mode */
556 rcode
= 1; /* failed */
560 /* show that we're waiting */
561 if ((now
- last
) > 1000) { /* every second */
567 flash_reset(info
); /* reset to read mode */
574 /*-----------------------------------------------------------------------
575 * Copy memory to flash, returns:
578 * 2 - Flash not erased
580 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
582 FPW data
= 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
583 int bytes
; /* number of bytes to program in current word */
584 int left
; /* number of bytes left to program */
587 for (left
= cnt
, res
= 0;
588 left
> 0 && res
== 0;
589 addr
+= sizeof(data
), left
-= sizeof(data
) - bytes
) {
591 bytes
= addr
& (sizeof(data
) - 1);
592 addr
&= ~(sizeof(data
) - 1);
594 /* combine source and destination data so can program
595 * an entire word of 16 or 32 bits
597 for (i
= 0; i
< sizeof(data
); i
++) {
599 if (i
< bytes
|| i
- bytes
>= left
)
600 data
+= *((uchar
*)addr
+ i
);
605 /* write one word to the flash */
606 switch (info
->flash_id
& FLASH_VENDMASK
) {
608 res
= write_word_amd(info
, (FPWV
*)addr
, data
);
610 case FLASH_MAN_INTEL
:
611 res
= write_word_intel(info
, (FPWV
*)addr
, data
);
614 /* unknown flash type, error! */
615 printf ("missing or unknown FLASH type\n");
616 res
= 1; /* not really a timeout, but gives error */
624 /*-----------------------------------------------------------------------
625 * Write a word to Flash for AMD FLASH
626 * A word is 16 or 32 bits, whichever the bus width of the flash bank
627 * (not an individual chip) is.
632 * 2 - Flash not erased
634 static int write_word_amd (flash_info_t
*info
, FPWV
*dest
, FPW data
)
638 int res
= 0; /* result, assume success */
639 FPWV
*base
; /* first address in flash bank */
641 /* Check if Flash is (sufficiently) erased */
642 if ((*dest
& data
) != data
) {
647 base
= (FPWV
*)(info
->start
[0]);
649 /* Disable interrupts which might cause a timeout here */
650 flag
= disable_interrupts();
652 base
[0x0555] = (FPW
)0x00AA00AA; /* unlock */
653 base
[0x02AA] = (FPW
)0x00550055; /* unlock */
654 base
[0x0555] = (FPW
)0x00A000A0; /* selects program mode */
656 *dest
= data
; /* start programming the data */
658 /* re-enable interrupts if necessary */
662 start
= get_timer (0);
664 /* data polling for D7 */
665 while (res
== 0 && (*dest
& (FPW
)0x00800080) != (data
& (FPW
)0x00800080)) {
666 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
667 *dest
= (FPW
)0x00F000F0; /* reset bank */
675 /*-----------------------------------------------------------------------
676 * Write a word to Flash for Intel FLASH
677 * A word is 16 or 32 bits, whichever the bus width of the flash bank
678 * (not an individual chip) is.
683 * 2 - Flash not erased
685 static int write_word_intel (flash_info_t
*info
, FPWV
*dest
, FPW data
)
689 int res
= 0; /* result, assume success */
691 /* Check if Flash is (sufficiently) erased */
692 if ((*dest
& data
) != data
) {
696 /* Disable interrupts which might cause a timeout here */
697 flag
= disable_interrupts();
699 *dest
= (FPW
)0x00500050; /* clear status register */
700 *dest
= (FPW
)0x00FF00FF; /* make sure in read mode */
701 *dest
= (FPW
)0x00400040; /* program setup */
703 *dest
= data
; /* start programming the data */
705 /* re-enable interrupts if necessary */
709 start
= get_timer (0);
711 while (res
== 0 && (*dest
& (FPW
)0x00800080) != (FPW
)0x00800080) {
712 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
713 *dest
= (FPW
)0x00B000B0; /* Suspend program */
718 if (res
== 0 && (*dest
& (FPW
)0x00100010))
719 res
= 1; /* write failed, time out error is close enough */
721 *dest
= (FPW
)0x00500050; /* clear status register */
722 *dest
= (FPW
)0x00FF00FF; /* make sure in read mode */
727 #ifdef CFG_FLASH_PROTECTION
728 /*-----------------------------------------------------------------------
730 int flash_real_protect (flash_info_t
* info
, long sector
, int prot
)
732 int rcode
= 0; /* assume success */
733 FPWV
*addr
; /* address of sector */
736 addr
= (FPWV
*) (info
->start
[sector
]);
738 switch (info
->flash_id
& FLASH_TYPEMASK
) {
739 case FLASH_28F800C3B
:
740 case FLASH_28F800C3T
:
741 case FLASH_28F160C3B
:
742 case FLASH_28F160C3T
:
743 case FLASH_28F320C3B
:
744 case FLASH_28F320C3T
:
745 case FLASH_28F640C3B
:
746 case FLASH_28F640C3T
:
747 flash_reset (info
); /* make sure in read mode */
748 *addr
= (FPW
) 0x00600060L
; /* lock command setup */
750 *addr
= (FPW
) 0x00010001L
; /* lock sector */
752 *addr
= (FPW
) 0x00D000D0L
; /* unlock sector */
753 flash_reset (info
); /* reset to read mode */
755 /* now see if it really is locked/unlocked as requested */
756 *addr
= (FPW
) 0x00900090;
757 /* read sector protection at sector address, (A7 .. A0) = 0x02.
758 * D0 = 1 for each device if protected.
759 * If at least one device is protected the sector is marked
760 * protected, but return failure. Mixed protected and
761 * unprotected devices within a sector should never happen.
763 value
= addr
[2] & (FPW
) 0x00010001;
765 info
->protect
[sector
] = 0;
766 else if (value
== (FPW
) 0x00010001)
767 info
->protect
[sector
] = 1;
769 /* error, mixed protected and unprotected */
771 info
->protect
[sector
] = 1;
773 if (info
->protect
[sector
] != prot
)
774 rcode
= 1; /* failed to protect/unprotect as requested */
776 /* reload all protection bits from hardware for now */
777 flash_sync_real_protect (info
);
783 /* no hardware protect that we support */
784 info
->protect
[sector
] = prot
;