]>
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
);
61 #define write_word(in, de, da) write_word_amd(in, de, da)
62 static void flash_get_offsets (ulong base
, flash_info_t
* info
);
64 #ifdef CFG_FLASH_PROTECTION
65 static void flash_sync_real_protect (flash_info_t
* info
);
68 /*-----------------------------------------------------------------------
71 * sets up flash_info and returns size of FLASH (bytes)
73 ulong
flash_init (void)
78 for (i
= 0; i
< CFG_MAX_FLASH_BANKS
; i
++) {
81 flash_info
[i
].flash_id
=
82 (FLASH_MAN_AMD
& FLASH_VENDMASK
) |
83 (FLASH_AM640U
& FLASH_TYPEMASK
);
84 flash_info
[i
].size
= FLASH_BANK_SIZE
;
85 flash_info
[i
].sector_count
= CFG_MAX_FLASH_SECT
;
86 memset (flash_info
[i
].protect
, 0, CFG_MAX_FLASH_SECT
);
89 flashbase
= PHYS_FLASH_1
;
92 flashbase
= PHYS_FLASH_2
;
95 panic ("configured to many flash banks!\n");
98 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, &flash_info
[0]);
118 /*-----------------------------------------------------------------------
120 static void flash_reset (flash_info_t
* info
)
122 FPWV
*base
= (FPWV
*) (info
->start
[0]);
124 /* Put FLASH back in read mode */
125 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
)
126 *base
= (FPW
) 0x00FF00FF; /* Intel Read Mode */
127 else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
)
128 *base
= (FPW
) 0x00F000F0; /* AMD Read Mode */
131 /*-----------------------------------------------------------------------
133 static void flash_get_offsets (ulong base
, flash_info_t
* info
)
137 /* set up sector start address table */
138 if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
139 && (info
->flash_id
& FLASH_BTYPE
)) {
140 int bootsect_size
; /* number of bytes/boot sector */
141 int sect_size
; /* number of bytes/regular sector */
143 bootsect_size
= 0x00002000 * (sizeof (FPW
) / 2);
144 sect_size
= 0x00010000 * (sizeof (FPW
) / 2);
146 /* set sector offsets for bottom boot block type */
147 for (i
= 0; i
< 8; ++i
) {
148 info
->start
[i
] = base
+ (i
* bootsect_size
);
150 for (i
= 8; i
< info
->sector_count
; i
++) {
151 info
->start
[i
] = base
+ ((i
- 7) * sect_size
);
153 } else if ((info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_AMD
154 && (info
->flash_id
& FLASH_TYPEMASK
) == FLASH_AM640U
) {
156 int sect_size
; /* number of bytes/sector */
158 sect_size
= 0x00010000 * (sizeof (FPW
) / 2);
160 /* set up sector start address table (uniform sector type) */
161 for (i
= 0; i
< info
->sector_count
; i
++)
162 info
->start
[i
] = base
+ (i
* sect_size
);
166 /*-----------------------------------------------------------------------
169 void flash_print_info (flash_info_t
* info
)
175 uchar botbootletter
[] = "B";
176 uchar topbootletter
[] = "T";
177 uchar botboottype
[] = "bottom boot sector";
178 uchar topboottype
[] = "top boot sector";
180 if (info
->flash_id
== FLASH_UNKNOWN
) {
181 printf ("missing or unknown FLASH type\n");
185 switch (info
->flash_id
& FLASH_VENDMASK
) {
190 printf ("BRIGHT MICRO ");
201 case FLASH_MAN_INTEL
:
205 printf ("Unknown Vendor ");
209 /* check for top or bottom boot, if it applies */
210 if (info
->flash_id
& FLASH_BTYPE
) {
211 boottype
= botboottype
;
212 bootletter
= botbootletter
;
214 boottype
= topboottype
;
215 bootletter
= topbootletter
;
218 switch (info
->flash_id
& FLASH_TYPEMASK
) {
220 fmt
= "29LV641D (64 Mbit, uniform sectors)\n";
222 case FLASH_28F800C3B
:
223 case FLASH_28F800C3T
:
224 fmt
= "28F800C3%s (8 Mbit, %s)\n";
226 case FLASH_INTEL800B
:
227 case FLASH_INTEL800T
:
228 fmt
= "28F800B3%s (8 Mbit, %s)\n";
230 case FLASH_28F160C3B
:
231 case FLASH_28F160C3T
:
232 fmt
= "28F160C3%s (16 Mbit, %s)\n";
234 case FLASH_INTEL160B
:
235 case FLASH_INTEL160T
:
236 fmt
= "28F160B3%s (16 Mbit, %s)\n";
238 case FLASH_28F320C3B
:
239 case FLASH_28F320C3T
:
240 fmt
= "28F320C3%s (32 Mbit, %s)\n";
242 case FLASH_INTEL320B
:
243 case FLASH_INTEL320T
:
244 fmt
= "28F320B3%s (32 Mbit, %s)\n";
246 case FLASH_28F640C3B
:
247 case FLASH_28F640C3T
:
248 fmt
= "28F640C3%s (64 Mbit, %s)\n";
250 case FLASH_INTEL640B
:
251 case FLASH_INTEL640T
:
252 fmt
= "28F640B3%s (64 Mbit, %s)\n";
255 fmt
= "Unknown Chip Type\n";
259 printf (fmt
, bootletter
, boottype
);
261 printf (" Size: %ld MB in %d Sectors\n",
262 info
->size
>> 20, info
->sector_count
);
264 printf (" Sector Start Addresses:");
266 for (i
= 0; i
< info
->sector_count
; ++i
) {
271 printf (" %08lX%s", info
->start
[i
],
272 info
->protect
[i
] ? " (RO)" : " ");
278 /*-----------------------------------------------------------------------
282 * The following code cannot be run from FLASH!
285 ulong
flash_get_size (FPWV
* addr
, flash_info_t
* info
)
287 /* Write auto select command: read Manufacturer ID */
289 /* Write auto select command sequence and test FLASH answer */
290 addr
[0x0555] = (FPW
) 0x00AA00AA; /* for AMD, Intel ignores this */
291 addr
[0x02AA] = (FPW
) 0x00550055; /* for AMD, Intel ignores this */
292 addr
[0x0555] = (FPW
) 0x00900090; /* selects Intel or AMD */
294 /* The manufacturer codes are only 1 byte, so just use 1 byte.
295 * This works for any bus width and any FLASH device width.
297 switch (addr
[0] & 0xff) {
299 case (uchar
) AMD_MANUFACT
:
300 info
->flash_id
= FLASH_MAN_AMD
;
303 case (uchar
) INTEL_MANUFACT
:
304 info
->flash_id
= FLASH_MAN_INTEL
;
308 info
->flash_id
= FLASH_UNKNOWN
;
309 info
->sector_count
= 0;
314 /* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */
315 if (info
->flash_id
!= FLASH_UNKNOWN
)
318 case (FPW
) AMD_ID_LV640U
: /* 29LV640 and 29LV641 have same ID */
319 info
->flash_id
+= FLASH_AM640U
;
320 info
->sector_count
= 128;
321 info
->size
= 0x00800000 * (sizeof (FPW
) / 2);
322 break; /* => 8 or 16 MB */
324 case (FPW
) INTEL_ID_28F800C3B
:
325 info
->flash_id
+= FLASH_28F800C3B
;
326 info
->sector_count
= 23;
327 info
->size
= 0x00100000 * (sizeof (FPW
) / 2);
328 break; /* => 1 or 2 MB */
330 case (FPW
) INTEL_ID_28F800B3B
:
331 info
->flash_id
+= FLASH_INTEL800B
;
332 info
->sector_count
= 23;
333 info
->size
= 0x00100000 * (sizeof (FPW
) / 2);
334 break; /* => 1 or 2 MB */
336 case (FPW
) INTEL_ID_28F160C3B
:
337 info
->flash_id
+= FLASH_28F160C3B
;
338 info
->sector_count
= 39;
339 info
->size
= 0x00200000 * (sizeof (FPW
) / 2);
340 break; /* => 2 or 4 MB */
342 case (FPW
) INTEL_ID_28F160B3B
:
343 info
->flash_id
+= FLASH_INTEL160B
;
344 info
->sector_count
= 39;
345 info
->size
= 0x00200000 * (sizeof (FPW
) / 2);
346 break; /* => 2 or 4 MB */
348 case (FPW
) INTEL_ID_28F320C3B
:
349 info
->flash_id
+= FLASH_28F320C3B
;
350 info
->sector_count
= 71;
351 info
->size
= 0x00400000 * (sizeof (FPW
) / 2);
352 break; /* => 4 or 8 MB */
354 case (FPW
) INTEL_ID_28F320B3B
:
355 info
->flash_id
+= FLASH_INTEL320B
;
356 info
->sector_count
= 71;
357 info
->size
= 0x00400000 * (sizeof (FPW
) / 2);
358 break; /* => 4 or 8 MB */
360 case (FPW
) INTEL_ID_28F640C3B
:
361 info
->flash_id
+= FLASH_28F640C3B
;
362 info
->sector_count
= 135;
363 info
->size
= 0x00800000 * (sizeof (FPW
) / 2);
364 break; /* => 8 or 16 MB */
366 case (FPW
) INTEL_ID_28F640B3B
:
367 info
->flash_id
+= FLASH_INTEL640B
;
368 info
->sector_count
= 135;
369 info
->size
= 0x00800000 * (sizeof (FPW
) / 2);
370 break; /* => 8 or 16 MB */
373 info
->flash_id
= FLASH_UNKNOWN
;
374 info
->sector_count
= 0;
376 return (0); /* => no or unknown flash */
379 flash_get_offsets ((ulong
) addr
, info
);
381 /* Put FLASH back in read mode */
387 #ifdef CFG_FLASH_PROTECTION
388 /*-----------------------------------------------------------------------
391 static void flash_sync_real_protect (flash_info_t
* info
)
393 FPWV
*addr
= (FPWV
*) (info
->start
[0]);
397 switch (info
->flash_id
& FLASH_TYPEMASK
) {
398 case FLASH_28F800C3B
:
399 case FLASH_28F800C3T
:
400 case FLASH_28F160C3B
:
401 case FLASH_28F160C3T
:
402 case FLASH_28F320C3B
:
403 case FLASH_28F320C3T
:
404 case FLASH_28F640C3B
:
405 case FLASH_28F640C3T
:
406 /* check for protected sectors */
407 *addr
= (FPW
) 0x00900090;
408 for (i
= 0; i
< info
->sector_count
; i
++) {
409 /* read sector protection at sector address, (A7 .. A0) = 0x02.
410 * D0 = 1 for each device if protected.
411 * If at least one device is protected the sector is marked
412 * protected, but mixed protected and unprotected devices
413 * within a sector should never happen.
415 sect
= (FPWV
*) (info
->start
[i
]);
416 info
->protect
[i
] = (sect
[2] & (FPW
) (0x00010001)) ? 1 : 0;
419 /* Put FLASH back in read mode */
425 /* no hardware protect that we support */
431 /*-----------------------------------------------------------------------
434 int flash_erase (flash_info_t
* info
, int s_first
, int s_last
)
437 int flag
, prot
, sect
;
438 int intel
= (info
->flash_id
& FLASH_VENDMASK
) == FLASH_MAN_INTEL
;
439 ulong start
, now
, last
;
442 if ((s_first
< 0) || (s_first
> s_last
)) {
443 if (info
->flash_id
== FLASH_UNKNOWN
) {
444 printf ("- missing\n");
446 printf ("- no sectors to erase\n");
451 switch (info
->flash_id
& FLASH_TYPEMASK
) {
452 case FLASH_INTEL800B
:
453 case FLASH_INTEL160B
:
454 case FLASH_INTEL320B
:
455 case FLASH_INTEL640B
:
456 case FLASH_28F800C3B
:
457 case FLASH_28F160C3B
:
458 case FLASH_28F320C3B
:
459 case FLASH_28F640C3B
:
464 printf ("Can't erase unknown flash type %08lx - aborted\n",
470 for (sect
= s_first
; sect
<= s_last
; ++sect
) {
471 if (info
->protect
[sect
]) {
477 printf ("- Warning: %d protected sectors will not be erased!\n",
483 start
= get_timer (0);
486 /* Start erase on unprotected sectors */
487 for (sect
= s_first
; sect
<= s_last
&& rcode
== 0; sect
++) {
489 if (info
->protect
[sect
] != 0) /* protected, skip it */
492 /* Disable interrupts which might cause a timeout here */
493 flag
= disable_interrupts ();
495 addr
= (FPWV
*) (info
->start
[sect
]);
497 *addr
= (FPW
) 0x00500050; /* clear status register */
498 *addr
= (FPW
) 0x00200020; /* erase setup */
499 *addr
= (FPW
) 0x00D000D0; /* erase confirm */
501 /* must be AMD style if not Intel */
502 FPWV
*base
; /* first address in bank */
504 base
= (FPWV
*) (info
->start
[0]);
505 base
[0x0555] = (FPW
) 0x00AA00AA; /* unlock */
506 base
[0x02AA] = (FPW
) 0x00550055; /* unlock */
507 base
[0x0555] = (FPW
) 0x00800080; /* erase mode */
508 base
[0x0555] = (FPW
) 0x00AA00AA; /* unlock */
509 base
[0x02AA] = (FPW
) 0x00550055; /* unlock */
510 *addr
= (FPW
) 0x00300030; /* erase sector */
513 /* re-enable interrupts if necessary */
515 enable_interrupts ();
517 /* wait at least 50us for AMD, 80us for Intel.
522 while ((*addr
& (FPW
) 0x00800080) != (FPW
) 0x00800080) {
523 if ((now
= get_timer (start
)) > CFG_FLASH_ERASE_TOUT
) {
524 printf ("Timeout\n");
528 *addr
= (FPW
) 0x00B000B0;
531 flash_reset (info
); /* reset to read mode */
532 rcode
= 1; /* failed */
536 /* show that we're waiting */
537 if ((now
- last
) > 1000) { /* every second */
543 flash_reset (info
); /* reset to read mode */
550 /*-----------------------------------------------------------------------
551 * Copy memory to flash, returns:
554 * 2 - Flash not erased
556 int bad_write_buff (flash_info_t
*info
, uchar
*src
, ulong addr
, ulong cnt
)
558 FPW data
= 0; /* 16 or 32 bit word, matches flash bus width */
559 int bytes
; /* number of bytes to program in current word */
560 int left
; /* number of bytes left to program */
563 /* printf("write_buff: src: %8p addr %08lx count: %ld\n", src, addr, cnt); */
565 for (left
= cnt
, res
= 0;
566 left
> 0 && res
== 0;
567 addr
+= sizeof (data
), left
-= sizeof (data
) - bytes
) {
569 bytes
= addr
& (sizeof (data
) - 1);
570 addr
&= ~(sizeof (data
) - 1);
572 /* combine source and destination data so can program
573 * an entire word of 16 or 32 bits
575 for (i
= 0; i
< sizeof (data
); i
++) {
577 if (i
< bytes
|| i
- bytes
>= left
)
578 data
+= *((uchar
*) addr
+ i
);
583 /* write one word to the flash */
584 switch (info
->flash_id
& FLASH_VENDMASK
) {
586 res
= write_word_amd (info
, (FPWV
*) addr
, data
);
588 case FLASH_MAN_INTEL
:
589 res
= write_word_intel (info
, (FPWV
*) addr
, data
);
592 /* unknown flash type, error! */
593 printf ("missing or unknown FLASH type\n");
594 res
= 1; /* not really a timeout, but gives error */
603 * write_buf: - Copy memory to flash.
606 * @param src: source of copy transaction
607 * @param addr: where to copy to
608 * @param cnt: number of bytes to copy
613 int write_buff (flash_info_t
* info
, uchar
* src
, ulong addr
, ulong cnt
)
620 wp
= (addr
& ~1); /* get lower word aligned address */
623 * handle unaligned start bytes
625 if ((l
= addr
- wp
) != 0) {
627 for (i
= 0, cp
= wp
; i
< l
; ++i
, ++cp
) {
628 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
630 for (; i
< 2 && cnt
> 0; ++i
) {
631 data
= (data
>> 8) | (*src
++ << 8);
635 for (; cnt
== 0 && i
< 2; ++i
, ++cp
) {
636 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
639 if ((rc
= write_word (info
, wp
, data
)) != 0) {
646 * handle word aligned part
649 /* data = *((vushort*)src); */
650 data
= *((FPW
*) src
);
651 if ((rc
= write_word (info
, wp
, data
)) != 0) {
663 * handle unaligned tail bytes
666 for (i
= 0, cp
= wp
; i
< 2 && cnt
> 0; ++i
, ++cp
) {
667 data
= (data
>> 8) | (*src
++ << 8);
670 for (; i
< 2; ++i
, ++cp
) {
671 data
= (data
>> 8) | (*(uchar
*) cp
<< 8);
674 return write_word (info
, wp
, data
);
679 /*-----------------------------------------------------------------------
680 * Write a word to Flash for AMD FLASH
681 * A word is 16 or 32 bits, whichever the bus width of the flash bank
682 * (not an individual chip) is.
687 * 2 - Flash not erased
689 static int write_word_amd (flash_info_t
* info
, FPWV
* dest
, FPW data
)
693 int res
= 0; /* result, assume success */
694 FPWV
*base
; /* first address in flash bank */
696 /* Check if Flash is (sufficiently) erased */
697 if ((*dest
& data
) != data
) {
702 base
= (FPWV
*) (info
->start
[0]);
703 /* Disable interrupts which might cause a timeout here */
704 flag
= disable_interrupts ();
706 base
[0x0555] = (FPW
) 0x00AA00AA; /* unlock */
707 base
[0x02AA] = (FPW
) 0x00550055; /* unlock */
708 base
[0x0555] = (FPW
) 0x00A000A0; /* selects program mode */
710 *dest
= data
; /* start programming the data */
712 /* re-enable interrupts if necessary */
714 enable_interrupts ();
716 start
= get_timer (0);
718 /* data polling for D7 */
720 && (*dest
& (FPW
) 0x00800080) != (data
& (FPW
) 0x00800080)) {
721 if (get_timer (start
) > CFG_FLASH_WRITE_TOUT
) {
722 *dest
= (FPW
) 0x00F000F0; /* reset bank */
730 /*-----------------------------------------------------------------------
731 * Write a word to Flash for Intel FLASH
732 * A word is 16 or 32 bits, whichever the bus width of the flash bank
733 * (not an individual chip) is.
738 * 2 - Flash not erased
740 static int write_word_intel (flash_info_t
* info
, FPWV
* dest
, FPW data
)
744 int res
= 0; /* result, assume success */
746 /* Check if Flash is (sufficiently) erased */
747 if ((*dest
& data
) != data
) {
751 /* Disable interrupts which might cause a timeout here */
752 flag
= disable_interrupts ();
754 *dest
= (FPW
) 0x00500050; /* clear status register */
755 *dest
= (FPW
) 0x00FF00FF; /* make sure in read mode */
756 *dest
= (FPW
) 0x00400040; /* program setup */
758 *dest
= data
; /* start programming the data */
760 /* re-enable interrupts if necessary */
762 enable_interrupts ();
764 start
= get_timer (0);
766 while (res
== 0 && (*dest
& (FPW
) 0x00800080) != (FPW
) 0x00800080) {
767 if (get_timer (start
) > CFG_FLASH_WRITE_TOUT
) {
768 *dest
= (FPW
) 0x00B000B0; /* Suspend program */
773 if (res
== 0 && (*dest
& (FPW
) 0x00100010))
774 res
= 1; /* write failed, time out error is close enough */
776 *dest
= (FPW
) 0x00500050; /* clear status register */
777 *dest
= (FPW
) 0x00FF00FF; /* make sure in read mode */
782 #ifdef CFG_FLASH_PROTECTION
783 /*-----------------------------------------------------------------------
785 int flash_real_protect (flash_info_t
* info
, long sector
, int prot
)
787 int rcode
= 0; /* assume success */
788 FPWV
*addr
; /* address of sector */
791 addr
= (FPWV
*) (info
->start
[sector
]);
793 switch (info
->flash_id
& FLASH_TYPEMASK
) {
794 case FLASH_28F800C3B
:
795 case FLASH_28F800C3T
:
796 case FLASH_28F160C3B
:
797 case FLASH_28F160C3T
:
798 case FLASH_28F320C3B
:
799 case FLASH_28F320C3T
:
800 case FLASH_28F640C3B
:
801 case FLASH_28F640C3T
:
802 flash_reset (info
); /* make sure in read mode */
803 *addr
= (FPW
) 0x00600060L
; /* lock command setup */
805 *addr
= (FPW
) 0x00010001L
; /* lock sector */
807 *addr
= (FPW
) 0x00D000D0L
; /* unlock sector */
808 flash_reset (info
); /* reset to read mode */
810 /* now see if it really is locked/unlocked as requested */
811 *addr
= (FPW
) 0x00900090;
812 /* read sector protection at sector address, (A7 .. A0) = 0x02.
813 * D0 = 1 for each device if protected.
814 * If at least one device is protected the sector is marked
815 * protected, but return failure. Mixed protected and
816 * unprotected devices within a sector should never happen.
818 value
= addr
[2] & (FPW
) 0x00010001;
820 info
->protect
[sector
] = 0;
821 else if (value
== (FPW
) 0x00010001)
822 info
->protect
[sector
] = 1;
824 /* error, mixed protected and unprotected */
826 info
->protect
[sector
] = 1;
828 if (info
->protect
[sector
] != prot
)
829 rcode
= 1; /* failed to protect/unprotect as requested */
831 /* reload all protection bits from hardware for now */
832 flash_sync_real_protect (info
);
837 /* no hardware protect that we support */
838 info
->protect
[sector
] = prot
;