diff --git a/CHANGELOG b/CHANGELOG index 34b8d20..4c5b62c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,33 @@ Changes since U-Boot 1.1.4: ====================================================================== +* Changes/fixes for drivers/cfi_flash.c: + + - Add Intel legacy lock/unlock support to common CFI driver + + On some Intel flash's (e.g. Intel J3) legacy unlocking is + supported, meaning that unlocking of one sector will unlock + all sectors of this bank. Using this feature, unlocking + of all sectors upon startup (via env var "unlock=yes") will + get much faster. + + - Fixed problem with multiple reads of envronment variable + "unlock" as pointed out by Reinhard Arlt & Anders Larsen. + + - Removed unwanted linefeeds from "protect" command when + CFG_FLASH_PROTECTION is enabled. + + - Changed p3p400 board to use CFG_FLASH_PROTECTION + + Patch by Stefan Roese, 01 Apr 2006 + +* Changes/fixes for drivers/cfi_flash.c: + - Correctly handle the cases where CFG_HZ != 1000 (several + XScale-based boards) + - Fix the timeout calculation of buffered writes (off by a + factor of 1000) + Patch by Anders Larsen, 31 Mar 2006 + * Enable Quad UART om MCC200 board. * Cleanup MCC200 board configuration; omit non-existent stuff. diff --git a/common/cmd_flash.c b/common/cmd_flash.c index 0aa4783..201f4e3 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -455,6 +455,7 @@ int do_protect (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #ifdef CONFIG_HAS_DATAFLASH int status; #endif + if (argc < 3) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; @@ -655,10 +656,10 @@ int flash_sect_protect (int p, ulong addr_first, ulong addr_last) #endif /* CFG_FLASH_PROTECTION */ } } + } #if defined(CFG_FLASH_PROTECTION) - if (!rcode) putc ('\n'); + puts (" done\n"); #endif /* CFG_FLASH_PROTECTION */ - } printf ("%sProtected %d sectors\n", p ? "" : "Un-", protected); diff --git a/drivers/cfi_flash.c b/drivers/cfi_flash.c index a989d34..2e37480 100644 --- a/drivers/cfi_flash.c +++ b/drivers/cfi_flash.c @@ -117,6 +117,7 @@ #define FLASH_OFFSET_CFI 0x55 #define FLASH_OFFSET_CFI_RESP 0x10 #define FLASH_OFFSET_PRIMARY_VENDOR 0x13 +#define FLASH_OFFSET_EXT_QUERY_T_P_ADDR 0x15 /* extended query table primary addr */ #define FLASH_OFFSET_WTOUT 0x1F #define FLASH_OFFSET_WBTOUT 0x20 #define FLASH_OFFSET_ETOUT 0x21 @@ -346,6 +347,10 @@ unsigned long flash_init (void) unsigned long size = 0; int i; +#ifdef CFG_FLASH_PROTECTION + char *s = getenv("unlock"); +#endif + /* Init: no FLASHes known */ for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) { flash_info[i].flash_id = FLASH_UNKNOWN; @@ -357,15 +362,39 @@ unsigned long flash_init (void) #endif /* CFG_FLASH_QUIET_TEST */ } #ifdef CFG_FLASH_PROTECTION - else { - char *s = getenv("unlock"); + else if ((s != NULL) && (strcmp(s, "yes") == 0)) { + /* + * Only the U-Boot image and it's environment is protected, + * all other sectors are unprotected (unlocked) if flash + * hardware protection is used (CFG_FLASH_PROTECTION) and + * the environment variable "unlock" is set to "yes". + */ + if (flash_info[i].legacy_unlock) { + int k; + + /* + * Disable legacy_unlock temporarily, since + * flash_real_protect would relock all other sectors + * again otherwise. + */ + flash_info[i].legacy_unlock = 0; - if (((s = getenv("unlock")) != NULL) && (strcmp(s, "yes") == 0)) { /* - * Only the U-Boot image and it's environment is protected, - * all other sectors are unprotected (unlocked) if flash - * hardware protection is used (CFG_FLASH_PROTECTION) and - * the environment variable "unlock" is set to "yes". + * Legacy unlocking (e.g. Intel J3) -> unlock only one + * sector. This will unlock all sectors. + */ + flash_real_protect (&flash_info[i], 0, 0); + + flash_info[i].legacy_unlock = 1; + + /* + * Manually mark other sectors as unlocked (unprotected) + */ + for (k = 1; k < flash_info[i].sector_count; k++) + flash_info[i].protect[k] = 0; + } else { + /* + * No legancy unlocking -> unlock all sectors */ flash_protect (FLAG_PROTECT_CLEAR, flash_info[i].start[0], @@ -668,8 +697,12 @@ int flash_real_protect (flash_info_t * info, long sector, int prot) prot ? "protect" : "unprotect")) == 0) { info->protect[sector] = prot; - /* Intel's unprotect unprotects all locking */ - if (prot == 0) { + + /* + * On some of Intel's flash chips (marked via legacy_unlock) + * unprotect unprotects all locking. + */ + if ((prot == 0) && (info->legacy_unlock)) { flash_sect_t i; for (i = 0; i < info->sector_count; i++) { @@ -746,6 +779,10 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector, { ulong start; +#if CFG_HZ != 1000 + tout *= CFG_HZ/1000; +#endif + /* Wait for command completion */ start = get_timer (0); while (flash_is_busy (info, sector)) { @@ -1082,6 +1119,10 @@ ulong flash_get_size (ulong base, int banknum) uchar num_erase_regions; int erase_region_size; int erase_region_count; +#ifdef CFG_FLASH_PROTECTION + int ext_addr; + info->legacy_unlock = 0; +#endif info->start[0] = base; @@ -1095,6 +1136,13 @@ ulong flash_get_size (ulong base, int banknum) case CFI_CMDSET_INTEL_EXTENDED: default: info->cmd_reset = FLASH_CMD_RESET; +#ifdef CFG_FLASH_PROTECTION + /* read legacy lock/unlock bit from intel flash */ + ext_addr = flash_read_ushort (info, 0, + FLASH_OFFSET_EXT_QUERY_T_P_ADDR); + info->legacy_unlock = + flash_read_uchar (info, ext_addr + 5) & 0x08; +#endif break; case CFI_CMDSET_AMD_STANDARD: case CFI_CMDSET_AMD_EXTENDED: @@ -1160,8 +1208,9 @@ ulong flash_get_size (ulong base, int banknum) info->buffer_size = (1 << flash_read_ushort (info, 0, FLASH_OFFSET_BUFFER_SIZE)); tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT); info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT))); - tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT); - info->buffer_write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT))); + tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT)) * + (1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT)); + info->buffer_write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */ tmp = (1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT)) * (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT)); info->write_tout = tmp / 1000 + (tmp % 1000 ? 1 : 0); /* round up when converting to ms */ diff --git a/include/configs/p3p440.h b/include/configs/p3p440.h index 831d018..19656fc 100644 --- a/include/configs/p3p440.h +++ b/include/configs/p3p440.h @@ -146,6 +146,7 @@ "cp.b 100000 fffc0000 40000;" \ "setenv filesize;saveenv\0" \ "upd=run load;run update\0" \ + "unlock=yes\0" \ "" #define CONFIG_BOOTCOMMAND "run net_nfs" @@ -275,6 +276,9 @@ #define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ +#define CFG_FLASH_PROTECTION 1 /* use hardware protection */ +#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ + #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ #define CFG_FLASH_QUIET_TEST 1 /* don't warn upon unknown flash */ diff --git a/include/flash.h b/include/flash.h index 4c68c68..a84dc68 100644 --- a/include/flash.h +++ b/include/flash.h @@ -45,6 +45,7 @@ typedef struct { ushort vendor; /* the primary vendor id */ ushort cmd_reset; /* Vendor specific reset command */ ushort interface; /* used for x8/x16 adjustments */ + ushort legacy_unlock; /* support Intel legacy (un)locking */ #endif } flash_info_t;