]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/logodl/flash.c
2 * (C) 2000 Wolfgang Denk, DENX Software Engineering, wd@denx.de.
3 * (C) 2003 August Hoeraendl, Logotronic GmbH
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,
24 #undef CONFIG_FLASH_16BIT
28 #define FLASH_BANK_SIZE 0x1000000
29 #define MAIN_SECT_SIZE 0x20000 /* 2x64k = 128k per sector */
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
;
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 #define write_word(in, de, da) write_word_amd(in, de, da)
61 static void flash_get_offsets(ulong base
, flash_info_t
*info
);
62 #ifdef CFG_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 ulong
flash_init(void)
76 for (i
= 0; i
< CFG_MAX_FLASH_BANKS
; i
++)
79 flash_info
[i
].flash_id
=
80 (FLASH_MAN_AMD
& FLASH_VENDMASK
) |
81 (FLASH_AM640U
& FLASH_TYPEMASK
);
82 flash_info
[i
].size
= FLASH_BANK_SIZE
;
83 flash_info
[i
].sector_count
= CFG_MAX_FLASH_SECT
;
84 memset(flash_info
[i
].protect
, 0, CFG_MAX_FLASH_SECT
);
88 flashbase
= PHYS_FLASH_1
;
91 flashbase
= PHYS_FLASH_2
;
94 panic("configured to many flash banks!\n");
97 for (j
= 0; j
< flash_info
[i
].sector_count
; j
++)
99 flash_info
[i
].start
[j
] = flashbase
+ j
*MAIN_SECT_SIZE
;
101 size
+= flash_info
[i
].size
;
104 /* Protect monitor and environment sectors
106 flash_protect(FLAG_PROTECT_SET
,
108 CFG_FLASH_BASE
+ _armboot_end_data
- _armboot_start
,
111 flash_protect(FLAG_PROTECT_SET
,
113 CFG_ENV_ADDR
+ CFG_ENV_SIZE
- 1,
119 /*-----------------------------------------------------------------------
121 static void flash_reset(flash_info_t
*info
)
123 FPWV
*base
= (FPWV
*)(info
->start
[0]);
125 /* Put FLASH back in read mode */
126 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
127 *base
= (FPW
)0x00FF00FF; /* Intel Read Mode */
128 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
)
129 *base
= (FPW
)0x00F000F0; /* AMD Read Mode */
132 /*-----------------------------------------------------------------------
134 static void flash_get_offsets (ulong base
, flash_info_t
*info
)
138 /* set up sector start address table */
139 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
140 && (info
->flash_id
& FLASH_BTYPE
)) {
141 int bootsect_size
; /* number of bytes/boot sector */
142 int sect_size
; /* number of bytes/regular sector */
144 bootsect_size
= 0x00002000 * (sizeof(FPW
)/2);
145 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
147 /* set sector offsets for bottom boot block type */
148 for (i
= 0; i
< 8; ++i
) {
149 info
->start
[i
] = base
+ (i
* bootsect_size
);
151 for (i
= 8; i
< info
->sector_count
; i
++) {
152 info
->start
[i
] = base
+ ((i
- 7) * sect_size
);
155 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
156 && (info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM640U
) {
158 int sect_size
; /* number of bytes/sector */
160 sect_size
= 0x00010000 * (sizeof(FPW
)/2);
162 /* set up sector start address table (uniform sector type) */
163 for( i
= 0; i
< info
->sector_count
; i
++ )
164 info
->start
[i
] = base
+ (i
* sect_size
);
168 /*-----------------------------------------------------------------------
171 void flash_print_info (flash_info_t
*info
)
177 uchar botbootletter
[] = "B";
178 uchar topbootletter
[] = "T";
179 uchar botboottype
[] = "bottom boot sector";
180 uchar topboottype
[] = "top boot sector";
182 if (info
->flash_id
== FLASH_UNKNOWN
) {
183 printf ("missing or unknown FLASH type\n");
187 switch (info
->flash_id
& FLASH_VENDMASK
) {
188 case FLASH_MAN_AMD
: printf ("AMD "); break;
189 case FLASH_MAN_BM
: printf ("BRIGHT MICRO "); break;
190 case FLASH_MAN_FUJ
: printf ("FUJITSU "); break;
191 case FLASH_MAN_SST
: printf ("SST "); break;
192 case FLASH_MAN_STM
: printf ("STM "); break;
193 case FLASH_MAN_INTEL
: printf ("INTEL "); break;
194 default: printf ("Unknown Vendor "); break;
197 /* check for top or bottom boot, if it applies */
198 if (info
->flash_id
& FLASH_BTYPE
) {
199 boottype
= botboottype
;
200 bootletter
= botbootletter
;
203 boottype
= topboottype
;
204 bootletter
= topbootletter
;
207 switch (info
->flash_id
& FLASH_TYPEMASK
) {
209 fmt
= "29LV641D (64 Mbit, uniform sectors)\n";
211 case FLASH_28F800C3B
:
212 case FLASH_28F800C3T
:
213 fmt
= "28F800C3%s (8 Mbit, %s)\n";
215 case FLASH_INTEL800B
:
216 case FLASH_INTEL800T
:
217 fmt
= "28F800B3%s (8 Mbit, %s)\n";
219 case FLASH_28F160C3B
:
220 case FLASH_28F160C3T
:
221 fmt
= "28F160C3%s (16 Mbit, %s)\n";
223 case FLASH_INTEL160B
:
224 case FLASH_INTEL160T
:
225 fmt
= "28F160B3%s (16 Mbit, %s)\n";
227 case FLASH_28F320C3B
:
228 case FLASH_28F320C3T
:
229 fmt
= "28F320C3%s (32 Mbit, %s)\n";
231 case FLASH_INTEL320B
:
232 case FLASH_INTEL320T
:
233 fmt
= "28F320B3%s (32 Mbit, %s)\n";
235 case FLASH_28F640C3B
:
236 case FLASH_28F640C3T
:
237 fmt
= "28F640C3%s (64 Mbit, %s)\n";
239 case FLASH_INTEL640B
:
240 case FLASH_INTEL640T
:
241 fmt
= "28F640B3%s (64 Mbit, %s)\n";
244 fmt
= "Unknown Chip Type\n";
248 printf (fmt
, bootletter
, boottype
);
250 printf (" Size: %ld MB in %d Sectors\n",
254 printf (" Sector Start Addresses:");
256 for (i
=0; i
<info
->sector_count
; ++i
) {
261 printf (" %08lX%s", info
->start
[i
],
262 info
->protect
[i
] ? " (RO)" : " ");
268 /*-----------------------------------------------------------------------
272 * The following code cannot be run from FLASH!
275 ulong
flash_get_size (FPWV
*addr
, flash_info_t
*info
)
277 /* Write auto select command: read Manufacturer ID */
279 /* Write auto select command sequence and test FLASH answer */
280 addr
[0x0555] = (FPW
)0x00AA00AA; /* for AMD, Intel ignores this */
281 addr
[0x02AA] = (FPW
)0x00550055; /* for AMD, Intel ignores this */
282 addr
[0x0555] = (FPW
)0x00900090; /* selects Intel or AMD */
284 /* The manufacturer codes are only 1 byte, so just use 1 byte.
285 * This works for any bus width and any FLASH device width.
287 switch (addr
[0] & 0xff) {
289 case (uchar
)AMD_MANUFACT
:
290 info
->flash_id
= FLASH_MAN_AMD
;
293 case (uchar
)INTEL_MANUFACT
:
294 info
->flash_id
= FLASH_MAN_INTEL
;
298 info
->flash_id
= FLASH_UNKNOWN
;
299 info
->sector_count
= 0;
304 /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
305 if (info
->flash_id
!= FLASH_UNKNOWN
) switch (addr
[1]) {
307 case (FPW
)AMD_ID_LV640U
: /* 29LV640 and 29LV641 have same ID */
308 info
->flash_id
+= FLASH_AM640U
;
309 info
->sector_count
= 128;
310 info
->size
= 0x00800000 * (sizeof(FPW
)/2);
311 break; /* => 8 or 16 MB */
313 case (FPW
)INTEL_ID_28F800C3B
:
314 info
->flash_id
+= FLASH_28F800C3B
;
315 info
->sector_count
= 23;
316 info
->size
= 0x00100000 * (sizeof(FPW
)/2);
317 break; /* => 1 or 2 MB */
319 case (FPW
)INTEL_ID_28F800B3B
:
320 info
->flash_id
+= FLASH_INTEL800B
;
321 info
->sector_count
= 23;
322 info
->size
= 0x00100000 * (sizeof(FPW
)/2);
323 break; /* => 1 or 2 MB */
325 case (FPW
)INTEL_ID_28F160C3B
:
326 info
->flash_id
+= FLASH_28F160C3B
;
327 info
->sector_count
= 39;
328 info
->size
= 0x00200000 * (sizeof(FPW
)/2);
329 break; /* => 2 or 4 MB */
331 case (FPW
)INTEL_ID_28F160B3B
:
332 info
->flash_id
+= FLASH_INTEL160B
;
333 info
->sector_count
= 39;
334 info
->size
= 0x00200000 * (sizeof(FPW
)/2);
335 break; /* => 2 or 4 MB */
337 case (FPW
)INTEL_ID_28F320C3B
:
338 info
->flash_id
+= FLASH_28F320C3B
;
339 info
->sector_count
= 71;
340 info
->size
= 0x00400000 * (sizeof(FPW
)/2);
341 break; /* => 4 or 8 MB */
343 case (FPW
)INTEL_ID_28F320B3B
:
344 info
->flash_id
+= FLASH_INTEL320B
;
345 info
->sector_count
= 71;
346 info
->size
= 0x00400000 * (sizeof(FPW
)/2);
347 break; /* => 4 or 8 MB */
349 case (FPW
)INTEL_ID_28F640C3B
:
350 info
->flash_id
+= FLASH_28F640C3B
;
351 info
->sector_count
= 135;
352 info
->size
= 0x00800000 * (sizeof(FPW
)/2);
353 break; /* => 8 or 16 MB */
355 case (FPW
)INTEL_ID_28F640B3B
:
356 info
->flash_id
+= FLASH_INTEL640B
;
357 info
->sector_count
= 135;
358 info
->size
= 0x00800000 * (sizeof(FPW
)/2);
359 break; /* => 8 or 16 MB */
362 info
->flash_id
= FLASH_UNKNOWN
;
363 info
->sector_count
= 0;
365 return (0); /* => no or unknown flash */
368 flash_get_offsets((ulong
)addr
, info
);
370 /* Put FLASH back in read mode */
376 #ifdef CFG_FLASH_PROTECTION
377 /*-----------------------------------------------------------------------
380 static void flash_sync_real_protect(flash_info_t
*info
)
382 FPWV
*addr
= (FPWV
*)(info
->start
[0]);
386 switch (info
->flash_id
& FLASH_TYPEMASK
) {
387 case FLASH_28F800C3B
:
388 case FLASH_28F800C3T
:
389 case FLASH_28F160C3B
:
390 case FLASH_28F160C3T
:
391 case FLASH_28F320C3B
:
392 case FLASH_28F320C3T
:
393 case FLASH_28F640C3B
:
394 case FLASH_28F640C3T
:
395 /* check for protected sectors */
396 *addr
= (FPW
)0x00900090;
397 for (i
= 0; i
< info
->sector_count
; i
++) {
398 /* read sector protection at sector address, (A7 .. A0) = 0x02.
399 * D0 = 1 for each device if protected.
400 * If at least one device is protected the sector is marked
401 * protected, but mixed protected and unprotected devices
402 * within a sector should never happen.
404 sect
= (FPWV
*)(info
->start
[i
]);
405 info
->protect
[i
] = (sect
[2] & (FPW
)(0x00010001)) ? 1 : 0;
408 /* Put FLASH back in read mode */
414 /* no hardware protect that we support */
420 /*-----------------------------------------------------------------------
423 int flash_erase (flash_info_t
*info
, int s_first
, int s_last
)
426 int flag
, prot
, sect
;
427 int intel
= (info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
;
428 ulong start
, now
, last
;
431 if ((s_first
< 0) || (s_first
> s_last
)) {
432 if (info
->flash_id
== FLASH_UNKNOWN
) {
433 printf ("- missing\n");
435 printf ("- no sectors to erase\n");
440 switch (info
->flash_id
& FLASH_TYPEMASK
) {
441 case FLASH_INTEL800B
:
442 case FLASH_INTEL160B
:
443 case FLASH_INTEL320B
:
444 case FLASH_INTEL640B
:
445 case FLASH_28F800C3B
:
446 case FLASH_28F160C3B
:
447 case FLASH_28F320C3B
:
448 case FLASH_28F640C3B
:
453 printf ("Can't erase unknown flash type %08lx - aborted\n",
459 for (sect
=s_first
; sect
<=s_last
; ++sect
) {
460 if (info
->protect
[sect
]) {
466 printf ("- Warning: %d protected sectors will not be erased!\n",
472 start
= get_timer(0);
475 /* Start erase on unprotected sectors */
476 for (sect
= s_first
; sect
<=s_last
&& rcode
== 0; sect
++) {
478 if (info
->protect
[sect
] != 0) /* protected, skip it */
481 /* Disable interrupts which might cause a timeout here */
482 flag
= disable_interrupts();
484 addr
= (FPWV
*)(info
->start
[sect
]);
486 *addr
= (FPW
)0x00500050; /* clear status register */
487 *addr
= (FPW
)0x00200020; /* erase setup */
488 *addr
= (FPW
)0x00D000D0; /* erase confirm */
491 /* must be AMD style if not Intel */
492 FPWV
*base
; /* first address in bank */
494 base
= (FPWV
*)(info
->start
[0]);
495 base
[0x0555] = (FPW
)0x00AA00AA; /* unlock */
496 base
[0x02AA] = (FPW
)0x00550055; /* unlock */
497 base
[0x0555] = (FPW
)0x00800080; /* erase mode */
498 base
[0x0555] = (FPW
)0x00AA00AA; /* unlock */
499 base
[0x02AA] = (FPW
)0x00550055; /* unlock */
500 *addr
= (FPW
)0x00300030; /* erase sector */
503 /* re-enable interrupts if necessary */
507 /* wait at least 50us for AMD, 80us for Intel.
512 while ((*addr
& (FPW
)0x00800080) != (FPW
)0x00800080) {
513 if ((now
= get_timer(start
)) > CFG_FLASH_ERASE_TOUT
) {
514 printf ("Timeout\n");
518 *addr
= (FPW
)0x00B000B0;
521 flash_reset(info
); /* reset to read mode */
522 rcode
= 1; /* failed */
526 /* show that we're waiting */
527 if ((now
- last
) > 1000) { /* every second */
533 flash_reset(info
); /* reset to read mode */
540 /*-----------------------------------------------------------------------
541 * Copy memory to flash, returns:
544 * 2 - Flash not erased
546 int bad_write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
548 FPW data
= 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
549 int bytes
; /* number of bytes to program in current word */
550 int left
; /* number of bytes left to program */
553 for (left
= cnt
, res
= 0;
554 left
> 0 && res
== 0;
555 addr
+= sizeof(data
), left
-= sizeof(data
) - bytes
) {
557 bytes
= addr
& (sizeof(data
) - 1);
558 addr
&= ~(sizeof(data
) - 1);
560 /* combine source and destination data so can program
561 * an entire word of 16 or 32 bits
563 for (i
= 0; i
< sizeof(data
); i
++) {
565 if (i
< bytes
|| i
- bytes
>= left
)
566 data
+= *((uchar
*)addr
+ i
);
571 /* write one word to the flash */
572 switch (info
->flash_id
& FLASH_VENDMASK
) {
574 res
= write_word_amd(info
, (FPWV
*)addr
, data
);
576 case FLASH_MAN_INTEL
:
577 res
= write_word_intel(info
, (FPWV
*)addr
, data
);
580 /* unknown flash type, error! */
581 printf ("missing or unknown FLASH type\n");
582 res
= 1; /* not really a timeout, but gives error */
591 * write_buf: - Copy memory to flash.
594 * @param src: source of copy transaction
595 * @param addr: where to copy to
596 * @param cnt: number of bytes to copy
601 int write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
608 wp
= (addr
& ~1); /* get lower word aligned address */
611 * handle unaligned start bytes
613 if ((l
= addr
- wp
) != 0) {
615 for (i
=0, cp
=wp
; i
<l
; ++i
, ++cp
) {
616 data
= (data
>> 8) | (*(uchar
*)cp
<< 8);
618 for (; i
<2 && cnt
>0; ++i
) {
619 data
= (data
>> 8) | (*src
++ << 8);
623 for (; cnt
==0 && i
<2; ++i
, ++cp
) {
624 data
= (data
>> 8) | (*(uchar
*)cp
<< 8);
627 if ((rc
= write_word(info
, wp
, data
)) != 0) {
634 * handle word aligned part
637 /* data = *((vushort*)src); */
639 if ((rc
= write_word(info
, wp
, data
)) != 0) {
647 if (cnt
== 0) return ERR_OK
;
650 * handle unaligned tail bytes
653 for (i
=0, cp
=wp
; i
<2 && cnt
>0; ++i
, ++cp
) {
654 data
= (data
>> 8) | (*src
++ << 8);
657 for (; i
<2; ++i
, ++cp
) {
658 data
= (data
>> 8) | (*(uchar
*)cp
<< 8);
661 return write_word(info
, wp
, data
);
666 /*-----------------------------------------------------------------------
667 * Write a word to Flash for AMD FLASH
668 * A word is 16 or 32 bits, whichever the bus width of the flash bank
669 * (not an individual chip) is.
674 * 2 - Flash not erased
676 static int write_word_amd (flash_info_t
*info
, FPWV
*dest
, FPW data
)
680 int res
= 0; /* result, assume success */
681 FPWV
*base
; /* first address in flash bank */
683 /* Check if Flash is (sufficiently) erased */
684 if ((*dest
& data
) != data
) {
689 base
= (FPWV
*)(info
->start
[0]);
690 /* Disable interrupts which might cause a timeout here */
691 flag
= disable_interrupts();
693 base
[0x0555] = (FPW
)0x00AA00AA; /* unlock */
694 base
[0x02AA] = (FPW
)0x00550055; /* unlock */
695 base
[0x0555] = (FPW
)0x00A000A0; /* selects program mode */
697 *dest
= data
; /* start programming the data */
699 /* re-enable interrupts if necessary */
703 start
= get_timer (0);
705 /* data polling for D7 */
706 while (res
== 0 && (*dest
& (FPW
)0x00800080) != (data
& (FPW
)0x00800080)) {
707 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
708 *dest
= (FPW
)0x00F000F0; /* reset bank */
716 /*-----------------------------------------------------------------------
717 * Write a word to Flash for Intel FLASH
718 * A word is 16 or 32 bits, whichever the bus width of the flash bank
719 * (not an individual chip) is.
724 * 2 - Flash not erased
726 static int write_word_intel (flash_info_t
*info
, FPWV
*dest
, FPW data
)
730 int res
= 0; /* result, assume success */
732 /* Check if Flash is (sufficiently) erased */
733 if ((*dest
& data
) != data
) {
737 /* Disable interrupts which might cause a timeout here */
738 flag
= disable_interrupts();
740 *dest
= (FPW
)0x00500050; /* clear status register */
741 *dest
= (FPW
)0x00FF00FF; /* make sure in read mode */
742 *dest
= (FPW
)0x00400040; /* program setup */
744 *dest
= data
; /* start programming the data */
746 /* re-enable interrupts if necessary */
750 start
= get_timer (0);
752 while (res
== 0 && (*dest
& (FPW
)0x00800080) != (FPW
)0x00800080) {
753 if (get_timer(start
) > CFG_FLASH_WRITE_TOUT
) {
754 *dest
= (FPW
)0x00B000B0; /* Suspend program */
759 if (res
== 0 && (*dest
& (FPW
)0x00100010))
760 res
= 1; /* write failed, time out error is close enough */
762 *dest
= (FPW
)0x00500050; /* clear status register */
763 *dest
= (FPW
)0x00FF00FF; /* make sure in read mode */
768 #ifdef CFG_FLASH_PROTECTION
769 /*-----------------------------------------------------------------------
771 int flash_real_protect (flash_info_t
* info
, long sector
, int prot
)
773 int rcode
= 0; /* assume success */
774 FPWV
*addr
; /* address of sector */
777 addr
= (FPWV
*) (info
->start
[sector
]);
779 switch (info
->flash_id
& FLASH_TYPEMASK
) {
780 case FLASH_28F800C3B
:
781 case FLASH_28F800C3T
:
782 case FLASH_28F160C3B
:
783 case FLASH_28F160C3T
:
784 case FLASH_28F320C3B
:
785 case FLASH_28F320C3T
:
786 case FLASH_28F640C3B
:
787 case FLASH_28F640C3T
:
788 flash_reset (info
); /* make sure in read mode */
789 *addr
= (FPW
) 0x00600060L
; /* lock command setup */
791 *addr
= (FPW
) 0x00010001L
; /* lock sector */
793 *addr
= (FPW
) 0x00D000D0L
; /* unlock sector */
794 flash_reset (info
); /* reset to read mode */
796 /* now see if it really is locked/unlocked as requested */
797 *addr
= (FPW
) 0x00900090;
798 /* read sector protection at sector address, (A7 .. A0) = 0x02.
799 * D0 = 1 for each device if protected.
800 * If at least one device is protected the sector is marked
801 * protected, but return failure. Mixed protected and
802 * unprotected devices within a sector should never happen.
804 value
= addr
[2] & (FPW
) 0x00010001;
806 info
->protect
[sector
] = 0;
807 else if (value
== (FPW
) 0x00010001)
808 info
->protect
[sector
] = 1;
810 /* error, mixed protected and unprotected */
812 info
->protect
[sector
] = 1;
814 if (info
->protect
[sector
] != prot
)
815 rcode
= 1; /* failed to protect/unprotect as requested */
817 /* reload all protection bits from hardware for now */
818 flash_sync_real_protect (info
);
823 /* no hardware protect that we support */
824 info
->protect
[sector
] = prot
;