u-boot-2013.07 移植到 mini2440 记录(二)

Nor Flash支持(SST39VF1601)


mini2440的配置文件include/configs/mini2440.h中对flash的设置为:

#define CONFIG_SYS_FLASH_CFI
#define CONFIG_FLASH_CFI_DRIVER
#define CONFIG_SYS_FLASH_CFI_WIDTH    FLASH_CFI_16BIT


CFI接口的flash驱动cfi_flash.c中,读取“QRY”的过程并不支持SST39VF1601,

SST37VF1601进入CFI QRY query模式要多两步,参照linux内核

修改如下:

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
old mode 100644
new mode 100755
index 25a5710..930395b
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -64,7 +64,7 @@
 * reading and writing ... (yes there is such a Hardware).
 */

-static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT };
+//static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT };
#ifdef CONFIG_FLASH_CFI_MTD
static uint flash_verbose = 1;
#else
@@ -546,6 +546,7 @@ static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
        break;
    case CFI_CMDSET_AMD_STANDARD:
    case CFI_CMDSET_AMD_EXTENDED:
+    case CFI_CMDSET_SST_OLD:
#ifdef CONFIG_FLASH_CFI_LEGACY
    case CFI_CMDSET_AMD_LEGACY:
#endif
@@ -823,14 +824,15 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
        flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_WRITE);
        sect_found = 1;
        break;
+    case CFI_CMDSET_SST_OLD:
#ifdef CONFIG_FLASH_CFI_LEGACY
    case CFI_CMDSET_AMD_LEGACY:
+#endif
        sect = find_sector(info, dest);
        flash_unlock_seq (info, 0);
        flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE);
        sect_found = 1;
        break;
-#endif
    }

    switch (info->portwidth) {
@@ -1133,6 +1135,9 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
                break;
#ifdef CONFIG_FLASH_CFI_LEGACY
            case CFI_CMDSET_AMD_LEGACY:
+#endif
+            case CFI_CMDSET_SST_OLD:
+
                flash_unlock_seq (info, 0);
                flash_write_cmd (info, 0, info->addr_unlock1,
                        AMD_CMD_ERASE_START);
@@ -1140,7 +1145,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
                flash_write_cmd (info, sect, 0,
                        AMD_CMD_ERASE_SECTOR);
                break;
-#endif
+
            default:
                debug ("Unkown flash vendor %d\n",
                       info->vendor);
@@ -1876,25 +1881,80 @@ static void __flash_cmd_reset(flash_info_t *info)
void flash_cmd_reset(flash_info_t *info)
    __attribute__((weak,alias("__flash_cmd_reset")));

+
+static int __cfi_qry_present(flash_info_t * info)
+{
+    if(flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
+        && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
+        && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y'))
+        return 1;
+    return 0;
+
+}
+static int __cfi_qry_mode_on(flash_info_t * info)
+{
+    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);//0xf0
+    flash_write_cmd (info, 0, 0x55, FLASH_CMD_CFI);//0x98
+    if( __cfi_qry_present(info))
+    {
+        info->cfi_offset = 0x55;
+        return 1;
+    }
+
+    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);//0xf0
+    flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);//0xff
+    flash_write_cmd (info, 0, 0x55, FLASH_CMD_CFI);
+    if( __cfi_qry_present(info))
+    {
+        info->cfi_offset = 0x55;
+        return 1;
+    }
+
+    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+    flash_write_cmd (info, 0, 0x555, FLASH_CMD_CFI);
+    if( __cfi_qry_present(info))
+    {
+        info->cfi_offset = 0x555;
+        return 1;
+    }
+
+    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+    flash_write_cmd (info, 0, 0x5555, 0xaa);
+    flash_write_cmd (info, 0, 0x2aaa, 0x55);
+    flash_write_cmd (info, 0, 0x5555, FLASH_CMD_CFI);
+    if( __cfi_qry_present(info))
+    {
+        info->cfi_offset = 0x5555;
+        return 1;
+    }
+
+    flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
+    flash_write_cmd (info, 0, 0x555, 0xAA);
+    flash_write_cmd (info, 0, 0x2AA, 0x55);
+    flash_write_cmd (info, 0, 0x555, FLASH_CMD_CFI);
+    if( __cfi_qry_present(info))
+    {
+        info->cfi_offset = 0x555;
+        return 1;
+    }
+    //QRY not found
+    return 0;
+}
+
static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
{
-    int cfi_offset;
+    //int cfi_offset;

    /* Issue FLASH reset command */
-    flash_cmd_reset(info);
-
-    for (cfi_offset = 0; cfi_offset < ARRAY_SIZE(flash_offset_cfi);
-         cfi_offset++) {
-        flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],
-                 FLASH_CMD_CFI);
-        if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
-            && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
-            && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+    //flash_cmd_reset(info);
+
+    //for (cfi_offset = 0; cfi_offset < ARRAY_SIZE(flash_offset_cfi);
+    //     cfi_offset++) {
+    if(__cfi_qry_mode_on(info)) {
            flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
                    sizeof(struct cfi_qry));
            info->interface    = le16_to_cpu(qry->interface_desc);

-            info->cfi_offset = flash_offset_cfi[cfi_offset];
            debug ("device interface is %d\n",
                   info->interface);
            debug ("found port %d chip %d ",
@@ -1921,15 +1981,21 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
                info->addr_unlock1 = 0xaaa;
                info->addr_unlock2 = 0x555;
            }
-
+            //for SST
+            if(le16_to_cpu(get_unaligned(&qry->p_id)) == CFI_CMDSET_SST_OLD)
+            {
+                info->addr_unlock1 = 0x5555;
+                info->addr_unlock2 = 0x2AAA;
+            }
            info->name = "CFI conformant";
            return 1;
-        }
    }

    return 0;
}

+
+
static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
{
    debug ("flash detect cfi\n");
@@ -1938,7 +2004,7 @@ static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
         info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
        for (info->chipwidth = FLASH_CFI_BY8;
             info->chipwidth <= info->portwidth;
-             info->chipwidth <<= 1)
+             info->chipwidth <<= 1)    
            if (__flash_detect_cfi(info, qry))
                return 1;
    }
@@ -2097,6 +2163,7 @@ ulong flash_get_size (phys_addr_t base, int banknum)
            break;
        case CFI_CMDSET_AMD_STANDARD:
        case CFI_CMDSET_AMD_EXTENDED:
+        case CFI_CMDSET_SST_OLD:
            cmdset_amd_init(info, &qry);
            break;
        default:

diff --git a/include/mtd/cfi_flash.h b/include/mtd/cfi_flash.h
old mode 100644
new mode 100755
index b644b91..0456877
--- a/include/mtd/cfi_flash.h
+++ b/include/mtd/cfi_flash.h
@@ -112,6 +112,7 @@
#define CFI_CMDSET_MITSU_STANDARD    256
#define CFI_CMDSET_MITSU_EXTENDED    257
#define CFI_CMDSET_SST            258
+#define CFI_CMDSET_SST_OLD     0x701
#define CFI_CMDSET_INTEL_PROG_REGIONS    512

#ifdef CONFIG_SYS_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */






你可能感兴趣的:(mini2440,u-boot,u-boot-2013.07,SST39VF1601)