Merge git://git.denx.de/u-boot-i2c
[oweals/u-boot.git] / drivers / mtd / cfi_flash.c
index e3cb59887ce096f2df8d1e16f8bad922e6132404..8a5babea7b3593efc64717cdbf40a8f3be816e08 100644 (file)
@@ -18,6 +18,7 @@
 /* #define DEBUG       */
 
 #include <common.h>
+#include <console.h>
 #include <dm.h>
 #include <errno.h>
 #include <fdt_support.h>
@@ -110,11 +111,9 @@ static void cfi_flash_init_dm(void)
        }
 }
 
-static phys_addr_t cfi_flash_base[CFI_MAX_FLASH_BANKS];
-
 phys_addr_t cfi_flash_bank_addr(int i)
 {
-       return cfi_flash_base[i];
+       return flash_info[i].base;
 }
 #else
 __weak phys_addr_t cfi_flash_bank_addr(int i)
@@ -177,7 +176,7 @@ __maybe_weak u64 flash_read64(void *addr)
 /*-----------------------------------------------------------------------
  */
 #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
-flash_info_t *flash_get_info(ulong base)
+static flash_info_t *flash_get_info(ulong base)
 {
        int i;
        flash_info_t *info;
@@ -354,8 +353,8 @@ static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,
 /*
  * Write a proper sized command to the correct address
  */
-void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
-                     uint offset, u32 cmd)
+static void flash_write_cmd(flash_info_t *info, flash_sect_t sect,
+                           uint offset, u32 cmd)
 {
 
        void *addr;
@@ -545,7 +544,16 @@ static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
 #ifdef CONFIG_FLASH_CFI_LEGACY
        case CFI_CMDSET_AMD_LEGACY:
 #endif
-               retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
+               if (info->sr_supported) {
+                       flash_write_cmd (info, sect, info->addr_unlock1,
+                                        FLASH_CMD_READ_STATUS);
+                       retval = !flash_isset (info, sect, 0,
+                                              FLASH_STATUS_DONE);
+               } else {
+                       retval = flash_toggle (info, sect, 0,
+                                              AMD_STATUS_TOGGLE);
+               }
+
                break;
        default:
                retval = 0;
@@ -607,7 +615,7 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
        case CFI_CMDSET_INTEL_EXTENDED:
        case CFI_CMDSET_INTEL_STANDARD:
                if ((retcode == ERR_OK)
-                   && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
+                   && !flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
                        retcode = ERR_INVAL;
                        printf ("Flash %s error at address %lx\n", prompt,
                                info->start[sector]);
@@ -978,7 +986,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 
        case CFI_CMDSET_AMD_STANDARD:
        case CFI_CMDSET_AMD_EXTENDED:
-               flash_unlock_seq(info,0);
+               flash_unlock_seq(info, sector);
 
 #ifdef CONFIG_FLASH_SPANSION_S29WS_N
                offset = ((unsigned long)dst - info->start[sector]) >> shift;
@@ -1455,8 +1463,8 @@ static int cfi_protect_bugfix(flash_info_t *info, long sector, int prot)
                                cmd = FLASH_CMD_PROTECT_SET;
                        else
                                cmd = FLASH_CMD_PROTECT_CLEAR;
-                               flash_write_cmd(info, sector, 0,
-                                         FLASH_CMD_PROTECT);
+
+                       flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
                        flash_write_cmd(info, sector, 0, cmd);
                        /* re-enable interrupts if necessary */
                        if (flag)
@@ -1686,6 +1694,7 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 {
        ushort bankId = 0;
        uchar  manuId;
+       uchar  lsbits;
 
        flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
        flash_unlock_seq(info, 0);
@@ -1701,6 +1710,9 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
        }
        info->manufacturer_id = manuId;
 
+       lsbits = flash_read_uchar(info, FLASH_OFFSET_LOWER_SW_BITS);
+       info->sr_supported = lsbits & BIT(0);
+
        switch (info->chipwidth){
        case FLASH_CFI_8BIT:
                info->device_id = flash_read_uchar (info,
@@ -2202,6 +2214,8 @@ ulong flash_get_size (phys_addr_t base, int banknum)
                                                flash_isset (info, sect_cnt,
                                                             FLASH_OFFSET_PROTECT,
                                                             FLASH_STATUS_PROTECT);
+                                       flash_write_cmd(info, sect_cnt, 0,
+                                                       FLASH_CMD_RESET);
                                        break;
                                case CFI_CMDSET_AMD_EXTENDED:
                                case CFI_CMDSET_AMD_STANDARD:
@@ -2295,7 +2309,7 @@ static void cfi_flash_set_config_reg(u32 base, u16 val)
 /*-----------------------------------------------------------------------
  */
 
-void flash_protect_default(void)
+static void flash_protect_default(void)
 {
 #if defined(CONFIG_SYS_FLASH_AUTOPROTECT_LIST)
        int i;
@@ -2350,7 +2364,7 @@ unsigned long flash_init (void)
 #ifdef CONFIG_SYS_FLASH_PROTECTION
        /* read environment from EEPROM */
        char s[64];
-       getenv_f("unlock", s, sizeof(s));
+       env_get_f("unlock", s, sizeof(s));
 #endif
 
 #ifdef CONFIG_CFI_FLASH /* for driver model */
@@ -2438,14 +2452,14 @@ unsigned long flash_init (void)
 static int cfi_flash_probe(struct udevice *dev)
 {
        void *blob = (void *)gd->fdt_blob;
-       int node = dev->of_offset;
+       int node = dev_of_offset(dev);
        const fdt32_t *cell;
        phys_addr_t addr;
        int parent, addrc, sizec;
        int len, idx;
 
        parent = fdt_parent_offset(blob, node);
-       of_bus_default_count_cells(blob, parent, &addrc, &sizec);
+       fdt_support_default_count_cells(blob, parent, &addrc, &sizec);
        /* decode regs, there may be multiple reg tuples. */
        cell = fdt_getprop(blob, node, "reg", &len);
        if (!cell)
@@ -2455,10 +2469,12 @@ static int cfi_flash_probe(struct udevice *dev)
        while (idx < len) {
                addr = fdt_translate_address((void *)blob,
                                             node, cell + idx);
-               cfi_flash_base[cfi_flash_num_flash_banks++] = addr;
+               flash_info[cfi_flash_num_flash_banks].dev = dev;
+               flash_info[cfi_flash_num_flash_banks].base = addr;
+               cfi_flash_num_flash_banks++;
                idx += addrc + sizec;
        }
-       gd->bd->bi_flashstart = cfi_flash_base[0];
+       gd->bd->bi_flashstart = flash_info[0].base;
 
        return 0;
 }