diff options
| -rw-r--r-- | drivers/mtd/cfi_flash.c | 52 | ||||
| -rw-r--r-- | include/mtd/cfi_flash.h | 7 | 
2 files changed, 59 insertions, 0 deletions
| diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 35294bc8c..50df9b0dd 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -1447,6 +1447,47 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)  							0, ATM_CMD_UNLOCK_SECT);  				}  			} +			if (info->manufacturer_id == (uchar)AMD_MANUFACT) { +				int flag = disable_interrupts(); +				int lock_flag; + +				flash_unlock_seq(info, 0); +				flash_write_cmd(info, 0, info->addr_unlock1, +						AMD_CMD_SET_PPB_ENTRY); +				lock_flag = flash_isset(info, sector, 0, 0x01); +				if (prot) { +					if (lock_flag) { +						flash_write_cmd(info, sector, 0, +							AMD_CMD_PPB_LOCK_BC1); +						flash_write_cmd(info, sector, 0, +							AMD_CMD_PPB_LOCK_BC2); +					} +					debug("sector %ld %slocked\n", sector, +						lock_flag ? "" : "already "); +				} else { +					if (!lock_flag) { +						debug("unlock %ld\n", sector); +						flash_write_cmd(info, 0, 0, +							AMD_CMD_PPB_UNLOCK_BC1); +						flash_write_cmd(info, 0, 0, +							AMD_CMD_PPB_UNLOCK_BC2); +					} +					debug("sector %ld %sunlocked\n", sector, +						!lock_flag ? "" : "already "); +				} +				if (flag) +					enable_interrupts(); + +				if (flash_status_check(info, sector, +						info->erase_blk_tout, +						prot ? "protect" : "unprotect")) +					printf("status check error\n"); + +				flash_write_cmd(info, 0, 0, +						AMD_CMD_SET_PPB_EXIT_BC1); +				flash_write_cmd(info, 0, 0, +						AMD_CMD_SET_PPB_EXIT_BC2); +			}  			break;  #ifdef CONFIG_FLASH_CFI_LEGACY  		case CFI_CMDSET_AMD_LEGACY: @@ -1635,6 +1676,17 @@ static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)  	cmdset_amd_read_jedec_ids(info);  	flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI); +#ifdef CONFIG_SYS_FLASH_PROTECTION +	if (info->ext_addr && info->manufacturer_id == (uchar)AMD_MANUFACT) { +		ushort spus; + +		/* read sector protect/unprotect scheme */ +		spus = flash_read_uchar(info, info->ext_addr + 9); +		if (spus == 0x8) +			info->legacy_unlock = 1; +	} +#endif +  	return 0;  } diff --git a/include/mtd/cfi_flash.h b/include/mtd/cfi_flash.h index 3245b443a..966b5e00c 100644 --- a/include/mtd/cfi_flash.h +++ b/include/mtd/cfi_flash.h @@ -60,6 +60,13 @@  #define AMD_CMD_UNLOCK_ACK		0x55  #define AMD_CMD_WRITE_TO_BUFFER		0x25  #define AMD_CMD_WRITE_BUFFER_CONFIRM	0x29 +#define AMD_CMD_SET_PPB_ENTRY		0xC0 +#define AMD_CMD_SET_PPB_EXIT_BC1	0x90 +#define AMD_CMD_SET_PPB_EXIT_BC2	0x00 +#define AMD_CMD_PPB_UNLOCK_BC1		0x80 +#define AMD_CMD_PPB_UNLOCK_BC2		0x30 +#define AMD_CMD_PPB_LOCK_BC1		0xA0 +#define AMD_CMD_PPB_LOCK_BC2		0x00  #define AMD_STATUS_TOGGLE		0x40  #define AMD_STATUS_ERROR		0x20 |