]> git.karo-electronics.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'next' of git://www.denx.de/git/u-boot-cfi-flash into next
authorWolfgang Denk <wd@denx.de>
Fri, 17 Dec 2010 19:11:54 +0000 (20:11 +0100)
committerWolfgang Denk <wd@denx.de>
Fri, 17 Dec 2010 19:11:54 +0000 (20:11 +0100)
drivers/mtd/cfi_flash.c
include/mtd/cfi_flash.h

index 39c235ebc2641978efa45bc69b28c0d2af63e3c8..b0068842f1c11c8c8eb25595cccc2b961b92a877 100644 (file)
@@ -74,6 +74,20 @@ flash_info_t flash_info[CFI_MAX_FLASH_BANKS];        /* FLASH chips info */
 #define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_8BIT
 #endif
 
+/*
+ * 0xffff is an undefined value for the configuration register. When
+ * this value is returned, the configuration register shall not be
+ * written at all (default mode).
+ */
+static u16 cfi_flash_config_reg(int i)
+{
+#ifdef CONFIG_SYS_CFI_FLASH_CONFIG_REGS
+       return ((u16 [])CONFIG_SYS_CFI_FLASH_CONFIG_REGS)[i];
+#else
+       return 0xffff;
+#endif
+}
+
 #if defined(CONFIG_SYS_MAX_FLASH_BANKS_DETECT)
 int cfi_flash_num_flash_banks = CONFIG_SYS_MAX_FLASH_BANKS_DETECT;
 #endif
@@ -1112,18 +1126,18 @@ static int sector_erased(flash_info_t *info, int i)
 {
        int k;
        int size;
-       volatile unsigned long *flash;
+       u32 *flash;
 
        /*
         * Check if whole sector is erased
         */
        size = flash_sector_size(info, i);
-       flash = (volatile unsigned long *) info->start[i];
+       flash = (u32 *)info->start[i];
        /* divide by 4 for longword access */
        size = size >> 2;
 
        for (k = 0; k < size; k++) {
-               if (*flash++ != 0xffffffff)
+               if (flash_read32(flash++) != 0xffffffff)
                        return 0;       /* not erased */
        }
 
@@ -1426,6 +1440,11 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
 #endif
        };
 
+       /*
+        * Flash needs to be in status register read mode for
+        * flash_full_status_check() to work correctly
+        */
+       flash_write_cmd(info, sector, 0, FLASH_CMD_READ_STATUS);
        if ((retcode =
             flash_full_status_check (info, sector, info->erase_blk_tout,
                                      prot ? "protect" : "unprotect")) == 0) {
@@ -1975,6 +1994,13 @@ ulong flash_get_size (phys_addr_t base, int banknum)
                                case CFI_CMDSET_INTEL_PROG_REGIONS:
                                case CFI_CMDSET_INTEL_EXTENDED:
                                case CFI_CMDSET_INTEL_STANDARD:
+                                       /*
+                                        * Set flash to read-id mode. Otherwise
+                                        * reading protected status is not
+                                        * guaranteed.
+                                        */
+                                       flash_write_cmd(info, sect_cnt, 0,
+                                                       FLASH_CMD_READ_ID);
                                        info->protect[sect_cnt] =
                                                flash_isset (info, sect_cnt,
                                                             FLASH_OFFSET_PROTECT,
@@ -2021,6 +2047,31 @@ void flash_set_verbose(uint v)
        flash_verbose = v;
 }
 
+static void cfi_flash_set_config_reg(u32 base, u16 val)
+{
+#ifdef CONFIG_SYS_CFI_FLASH_CONFIG_REGS
+       /*
+        * Only set this config register if really defined
+        * to a valid value (0xffff is invalid)
+        */
+       if (val == 0xffff)
+               return;
+
+       /*
+        * Set configuration register. Data is "encrypted" in the 16 lower
+        * address bits.
+        */
+       flash_write16(FLASH_CMD_SETUP, (void *)(base + (val << 1)));
+       flash_write16(FLASH_CMD_SET_CR_CONFIRM, (void *)(base + (val << 1)));
+
+       /*
+        * Finally issue reset-command to bring device back to
+        * read-array mode
+        */
+       flash_write16(FLASH_CMD_RESET, (void *)base);
+#endif
+}
+
 /*-----------------------------------------------------------------------
  */
 unsigned long flash_init (void)
@@ -2044,6 +2095,10 @@ unsigned long flash_init (void)
        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
                flash_info[i].flash_id = FLASH_UNKNOWN;
 
+               /* Optionally write flash configuration register */
+               cfi_flash_set_config_reg(cfi_flash_bank_addr(i),
+                                        cfi_flash_config_reg(i));
+
                if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))
                        flash_get_size(cfi_flash_bank_addr(i), i);
                size += flash_info[i].size;
index 2ff00f2fdd877b9339801c4a5051b360b0443e22..3245b443af4e0d5b02bb432337ebb79ae93e9b9f 100644 (file)
@@ -32,6 +32,8 @@
 #define FLASH_CMD_ERASE_CONFIRM                0xD0
 #define FLASH_CMD_WRITE                        0x40
 #define FLASH_CMD_PROTECT              0x60
+#define FLASH_CMD_SETUP                        0x60
+#define FLASH_CMD_SET_CR_CONFIRM       0x03
 #define FLASH_CMD_PROTECT_SET          0x01
 #define FLASH_CMD_PROTECT_CLEAR                0xD0
 #define FLASH_CMD_CLEAR_STATUS         0x50