]> git.kernelconcepts.de Git - karo-tx-redboot.git/commitdiff
TX51 pre-release
authorlothar <lothar>
Thu, 14 Jan 2010 16:22:53 +0000 (16:22 +0000)
committerlothar <lothar>
Thu, 14 Jan 2010 16:22:53 +0000 (16:22 +0000)
packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc.h
packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v2.h
packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v3.h
packages/devs/flash/arm/mxc/v2_0/include/mxcmci_host.h
packages/devs/flash/arm/mxc/v2_0/include/tx51_nand_bbt.h [new file with mode: 0644]
packages/devs/flash/arm/mxc/v2_0/src/mxc_mmc.c
packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c
packages/devs/flash/arm/mxc/v2_0/src/mxcmci_core.c
packages/devs/flash/arm/mxc/v2_0/src/mxcmci_host.c
packages/devs/flash/arm/mxc/v2_0/src/mxcmci_mmc.c

index fa7fbc591bcff42deb244f7b20bc142bf0b3e3ab..4e9b7642839013c0daaefb654c167d3f8cc2d0d5 100644 (file)
 #define NFC_BUFSIZE                                            0
 
 enum nfc_internal_buf {
-    RAM_BUF_0,
-    RAM_BUF_1,
-    RAM_BUF_2,
-    RAM_BUF_3,
-    RAM_BUF_4,
-    RAM_BUF_5,
-    RAM_BUF_6,
-    RAM_BUF_7,
+       RAM_BUF_0,
+       RAM_BUF_1,
+       RAM_BUF_2,
+       RAM_BUF_3,
+       RAM_BUF_4,
+       RAM_BUF_5,
+       RAM_BUF_6,
+       RAM_BUF_7,
 };
 
 enum nfc_output_mode {
-    FDO_PAGE_SPARE      = 0x0008,
-    FDO_SPARE_ONLY      = 0x1008,  // LSB has to be 0x08
-    FDO_FLASH_ID        = 0x0010,
-    FDO_FLASH_STATUS    = 0x0020,
+       FDO_PAGE_SPARE          = 0x0008,
+       FDO_SPARE_ONLY          = 0x1008,  // LSB has to be 0x08
+       FDO_FLASH_ID            = 0x0010,
+       FDO_FLASH_STATUS        = 0x0020,
 };
 
 #define wait_for_auto_prog_done()
+#define nfc_reg_read(a)        readl(a)
+#define nfc_reg_write(v,a)     writel(v,a)
 
 // Polls the NANDFC to wait for an operation to complete
-#define wait_op_done() CYG_MACRO_START                                                                                         \
-       volatile int mxc_nfc_wait_loop;                                                                                                 \
-       while (!(readw(NAND_FLASH_CONFIG2_REG) & NAND_FLASH_CONFIG2_INT_DONE)) {                \
-               for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++);      \
-       }                                                                                                                                                               \
+#define wait_op_done() CYG_MACRO_START                                                                 \
+       volatile int mxc_nfc_wait_loop;                                                                         \
+       while (!(readw(NAND_FLASH_CONFIG2_REG) & NAND_FLASH_CONFIG2_INT_DONE)) { \
+               for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++); \
+       }                                                                                                                                       \
 CYG_MACRO_END
 
 /*!
@@ -157,42 +159,42 @@ CYG_MACRO_END
  * @param ecc_en    1 - ecc enabled; 0 - ecc disabled
  */
 static void NFC_DATA_OUTPUT(enum nfc_internal_buf buf_no, enum nfc_output_mode mode,
-                            int ecc_en)
+                                                       int ecc_en)
 {
-    u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
+       u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
 
-    config1 |= readw(NAND_FLASH_CONFIG1_REG);
+       config1 |= readw(NAND_FLASH_CONFIG1_REG);
 
-    if (mode == FDO_SPARE_ONLY) {
-        config1 |= NAND_FLASH_CONFIG1_SP_EN;
-    }
+       if (mode == FDO_SPARE_ONLY) {
+               config1 |= NAND_FLASH_CONFIG1_SP_EN;
+       }
 
-    writew(config1, NAND_FLASH_CONFIG1_REG);
-    writew(buf_no, RAM_BUFFER_ADDRESS_REG);
-    writew(mode & 0xFF, NAND_FLASH_CONFIG2_REG);
-    wait_op_done();
+       writew(config1, NAND_FLASH_CONFIG1_REG);
+       writew(buf_no, RAM_BUFFER_ADDRESS_REG);
+       writew(mode & 0xFF, NAND_FLASH_CONFIG2_REG);
+       wait_op_done();
 }
 
 static void NFC_CMD_INPUT(u32 cmd)
 {
-    writew(cmd, NAND_FLASH_CMD_REG);
-    writew(NAND_FLASH_CONFIG2_FCMD_EN, NAND_FLASH_CONFIG2_REG);
-    wait_op_done();
+       writew(cmd, NAND_FLASH_CMD_REG);
+       writew(NAND_FLASH_CONFIG2_FCMD_EN, NAND_FLASH_CONFIG2_REG);
+       wait_op_done();
 }
 
 static u16 NFC_STATUS_READ(void)
 {
-    u16 flash_status;
-    u16 saved = readw(NAND_MAIN_BUF0);
+       u16 flash_status;
+       u16 saved = readw(NAND_MAIN_BUF0);
 
-    NFC_CMD_INPUT(FLASH_Status);
-    NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_STATUS, 1);
-    flash_status = readw(NAND_MAIN_BUF0) & 0x00FF;
+       NFC_CMD_INPUT(FLASH_Status);
+       NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_STATUS, 1);
+       flash_status = readw(NAND_MAIN_BUF0) & 0x00FF;
 
-    // restore
-    writew(saved, NAND_MAIN_BUF0);
+       // restore
+       writew(saved, NAND_MAIN_BUF0);
 
-    return flash_status;
+       return flash_status;
 }
 
 /*!
@@ -203,32 +205,32 @@ static u16 NFC_STATUS_READ(void)
  * @param ecc_en    1 - ecc enabled; 0 - ecc disabled
  */
 static void NFC_DATA_INPUT(enum nfc_internal_buf buf_no, enum nfc_page_area area,
-                           int ecc_en)
+                                               int ecc_en)
 {
-    u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
+       u16 config1 = (ecc_en != 0) ? NAND_FLASH_CONFIG1_ECC_EN : 0;
 
-    config1 |= readw(NAND_FLASH_CONFIG1_REG);
+       config1 |= readw(NAND_FLASH_CONFIG1_REG);
 
-    if (area == NFC_SPARE_ONLY) {
-        config1 |= NAND_FLASH_CONFIG1_SP_EN;
+       if (area == NFC_SPARE_ONLY) {
+               config1 |= NAND_FLASH_CONFIG1_SP_EN;
 #ifdef CYGPKG_HAL_ARM_MXC91221
-        config1 &= ~NAND_FLASH_CONFIG1_ECC_EN;
+               config1 &= ~NAND_FLASH_CONFIG1_ECC_EN;
 #endif
-    }
+       }
 
-    writew(config1, NAND_FLASH_CONFIG1_REG);
-    writew(buf_no, RAM_BUFFER_ADDRESS_REG);
+       writew(config1, NAND_FLASH_CONFIG1_REG);
+       writew(buf_no, RAM_BUFFER_ADDRESS_REG);
 
-    // start operation
-    writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
-    wait_op_done();
+       // start operation
+       writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
+       wait_op_done();
 }
 
 static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
 {
-    writew(buf_no, RAM_BUFFER_ADDRESS_REG);
-    writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
-    wait_op_done();
+       writew(buf_no, RAM_BUFFER_ADDRESS_REG);
+       writew(NAND_FLASH_CONFIG2_FDI_EN, NAND_FLASH_CONFIG2_REG);
+       wait_op_done();
 }
 
 /*!
@@ -236,19 +238,19 @@ static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
  */
 static void NFC_PRESET(u32 max_block_count)
 {
-    // Unlock the internal RAM buffer
-    writew(NFC_CONFIGURATION_UNLOCKED, NFC_CONFIGURATION_REG);
-    // First Block to be unlocked
-    writew(0, UNLOCK_START_BLK_ADD_REG);
-    // Last Unlock Block
-    writew(max_block_count, UNLOCK_END_BLK_ADD_REG);
-    // Unlock Block Command
-    writew(NF_WR_PROT_UNLOCK, NF_WR_PROT_REG);
+       // Unlock the internal RAM buffer
+       writew(NFC_CONFIGURATION_UNLOCKED, NFC_CONFIGURATION_REG);
+       // First Block to be unlocked
+       writew(0, UNLOCK_START_BLK_ADD_REG);
+       // Last Unlock Block
+       writew(max_block_count, UNLOCK_END_BLK_ADD_REG);
+       // Unlock Block Command
+       writew(NF_WR_PROT_UNLOCK, NF_WR_PROT_REG);
 }
 
 static void NFC_SET_NFC_ACTIVE_CS(u32 cs_line)
 {
-    // not needed.
+       // not needed.
 }
 
 /*!
@@ -257,9 +259,9 @@ static void NFC_SET_NFC_ACTIVE_CS(u32 cs_line)
  */
 static void NFC_ADDR_INPUT(u32 addr)
 {
-    writew(addr & ((1 << ADDR_INPUT_SIZE) - 1), NAND_FLASH_ADD_REG);
-    writew(NAND_FLASH_CONFIG2_FADD_EN, NAND_FLASH_CONFIG2_REG);
-    wait_op_done();
+       writew(addr & ((1 << ADDR_INPUT_SIZE) - 1), NAND_FLASH_ADD_REG);
+       writew(NAND_FLASH_CONFIG2_FADD_EN, NAND_FLASH_CONFIG2_REG);
+       wait_op_done();
 }
 
 #if defined(NFC_V1_1)
@@ -282,12 +284,12 @@ CYG_MACRO_END
 #define NFC_ARCH_INIT()
 #endif /*NFC_V1_1*/
 
-#define NAND_ADD0_REG       0xDEADDAED
-#define NAND_ADD8_REG       0xDEADDAED
-#define NAND_CMD_REG        0xDEADDAED
-#define NAND_LAUNCH_AUTO_PROG        0xDEADDAED
-#define NAND_STATUS_SUM_REG          0xDEADDAED
-#define NAND_LAUNCH_AUTO_READ        0xDEADDAED
-#define NAND_LAUNCH_AUTO_ERASE       0xDEADDAED
+#define NAND_ADD0_REG                          0xDEADDAED
+#define NAND_ADD8_REG                          0xDEADDAED
+#define NAND_CMD_REG                           0xDEADDAED
+#define NAND_LAUNCH_AUTO_PROG          0xDEADDAED
+#define NAND_STATUS_SUM_REG                    0xDEADDAED
+#define NAND_LAUNCH_AUTO_READ          0xDEADDAED
+#define NAND_LAUNCH_AUTO_ERASE         0xDEADDAED
 
 #endif // _MXC_NFC_H_
index da2b424293d6c96023d11b2b8970da0488b16ad5..f0de7ee103a1b1164516bbd464c11045d3f6742b 100644 (file)
@@ -55,7 +55,7 @@
 #include <pkgconf/devs_flash_onmxc.h>
 #include "mxc_nand_specifics.h"
 
-#define PG_2K_DATA_OP_MULTI_CYCLES()        false
+#define PG_2K_DATA_OP_MULTI_CYCLES()           false
 
 //----------------------------------------------------------------------------
 // Common device details.
@@ -111,10 +111,10 @@ enum nfc_internal_buf {
 };
 
 enum nfc_output_mode {
-       FDO_PAGE_SPARE      = 0x0008,
-       FDO_SPARE_ONLY      = 0x1008,  // LSB has to be 0x08
-       FDO_FLASH_ID        = 0x0010,
-       FDO_FLASH_STATUS    = 0x0020,
+       FDO_PAGE_SPARE          = 0x0008,
+       FDO_SPARE_ONLY          = 0x1008,  // LSB has to be 0x08
+       FDO_FLASH_ID            = 0x0010,
+       FDO_FLASH_STATUS        = 0x0020,
 };
 
 #define wait_for_auto_prog_done()
index a604287b055e978bdadfb22280941b79cfaccd20..d17782dcf1aefd49ba8d1e7719ef425f009c37ae 100644 (file)
 #include <pkgconf/devs_flash_onmxc.h>
 #include "mxc_nand_specifics.h"
 
-#define PG_2K_DATA_OP_MULTI_CYCLES()        false
-#define ADDR_INPUT_SIZE                 8
-
-#define NAND_MAIN_BUF0                  (NFC_BASE + 0x000)
-#define NAND_MAIN_BUF1                  (NFC_BASE + 0x200)
-#define NAND_MAIN_BUF2                  (NFC_BASE + 0x400)
-#define NAND_MAIN_BUF3                  (NFC_BASE + 0x600)
-#define NAND_MAIN_BUF4                  (NFC_BASE + 0x800)
-#define NAND_MAIN_BUF5                  (NFC_BASE + 0xA00)
-#define NAND_MAIN_BUF6                  (NFC_BASE + 0xC00)
-#define NAND_MAIN_BUF7                  (NFC_BASE + 0xE00)
-#define NAND_SPAR_BUF0                  (NFC_BASE + 0x1000)
-#define NAND_SPAR_BUF1                  (NFC_BASE + 0x1040)
-#define NAND_SPAR_BUF2                  (NFC_BASE + 0x1080)
-#define NAND_SPAR_BUF3                  (NFC_BASE + 0x10C0)
-#define NAND_SPAR_BUF4                  (NFC_BASE + 0x1100)
-#define NAND_SPAR_BUF5                  (NFC_BASE + 0x1140)
-#define NAND_SPAR_BUF6                  (NFC_BASE + 0x1180)
-#define NAND_SPAR_BUF7                  (NFC_BASE + 0x11C0)
+#define PG_2K_DATA_OP_MULTI_CYCLES()   false
+#define ADDR_INPUT_SIZE                                        8
+
+#define NAND_MAIN_BUF0                                 (NFC_BASE + 0x000)
+#define NAND_MAIN_BUF1                                 (NFC_BASE + 0x200)
+#define NAND_MAIN_BUF2                                 (NFC_BASE + 0x400)
+#define NAND_MAIN_BUF3                                 (NFC_BASE + 0x600)
+#define NAND_MAIN_BUF4                                 (NFC_BASE + 0x800)
+#define NAND_MAIN_BUF5                                 (NFC_BASE + 0xA00)
+#define NAND_MAIN_BUF6                                 (NFC_BASE + 0xC00)
+#define NAND_MAIN_BUF7                                 (NFC_BASE + 0xE00)
+#define NAND_SPAR_BUF0                                 (NFC_BASE + 0x1000)
+#define NAND_SPAR_BUF1                                 (NFC_BASE + 0x1040)
+#define NAND_SPAR_BUF2                                 (NFC_BASE + 0x1080)
+#define NAND_SPAR_BUF3                                 (NFC_BASE + 0x10C0)
+#define NAND_SPAR_BUF4                                 (NFC_BASE + 0x1100)
+#define NAND_SPAR_BUF5                                 (NFC_BASE + 0x1140)
+#define NAND_SPAR_BUF6                                 (NFC_BASE + 0x1180)
+#define NAND_SPAR_BUF7                                 (NFC_BASE + 0x11C0)
 
 // The following defines are not used. Just for compilation purpose
-#define ECC_STATUS_RESULT_REG     0xDEADFFFF
+#define ECC_STATUS_RESULT_REG                  0xDEADFFFF
 #define NFC_DATA_INPUT(buf_no, earea, en)
 #define NFC_DATA_INPUT_2k(buf_no)
 // dummy function as it is not needed for automatic operations
 #define NFC_ADDR_INPUT(addr)
 #define NFC_ARCH_INIT()
-#define NUM_OF_CS_LINES                 8
-#define NFC_BUFSIZE                          4096
+#define NUM_OF_CS_LINES                                           8
+#define NFC_BUFSIZE                                            4096
+#define NFC_SPARE_BUF_SZ                                 64
 
 enum nfc_internal_buf {
-    RAM_BUF_0 = 0x0 << 4,
-    RAM_BUF_1 = 0x1 << 4,
-    RAM_BUF_2 = 0x2 << 4,
-    RAM_BUF_3 = 0x3 << 4,
-    RAM_BUF_4 = 0x4 << 4,
-    RAM_BUF_5 = 0x5 << 4,
-    RAM_BUF_6 = 0x6 << 4,
-    RAM_BUF_7 = 0x7 << 4,
+       RAM_BUF_0 = 0x0 << 4,
+       RAM_BUF_1 = 0x1 << 4,
+       RAM_BUF_2 = 0x2 << 4,
+       RAM_BUF_3 = 0x3 << 4,
+       RAM_BUF_4 = 0x4 << 4,
+       RAM_BUF_5 = 0x5 << 4,
+       RAM_BUF_6 = 0x6 << 4,
+       RAM_BUF_7 = 0x7 << 4,
 };
 
 enum nfc_output_mode {
-    FDO_PAGE_SPARE      = 0x0008,
-    FDO_SPARE_ONLY      = 0x1008,  // LSB has to be 0x08
-    FDO_FLASH_ID        = 0x0010,
-    FDO_FLASH_STATUS    = 0x0020,
+       FDO_PAGE_SPARE          = 0x0008,
+       FDO_SPARE_ONLY          = 0x1008,  // LSB has to be 0x08
+       FDO_FLASH_ID            = 0x0010,
+       FDO_FLASH_STATUS        = 0x0020,
 };
 
-#define wait_for_auto_prog_done()                                                                                                                      \
-       do {                                                                                                                                                                    \
-               while ((nfc_reg_read(NFC_IPC_REG) & NFC_IPC_AUTO_DONE) == 0) {                                          \
-               }                                                                                                                                                                       \
-               write_nfc_ip_reg((nfc_reg_read(NFC_IPC_REG) & ~NFC_IPC_AUTO_DONE), NFC_IPC_REG);        \
-       } while (0)
+#if 1
+#define MAX_LOOPS 10000
+#define wait_for_auto_prog_done()                                                                              \
+       CYG_MACRO_START                                                                                                         \
+       int loops = MAX_LOOPS;                                                                                          \
+       static int max_loops = MAX_LOOPS;                                                                       \
+       while ((nfc_reg_read(NFC_IPC_REG) & NFC_IPC_AUTO_DONE) == 0) {          \
+               HAL_DELAY_US(10);                                                                                               \
+               if (loops-- < 0) {                                                                                              \
+                       diag_printf("%s: Timeout waiting for prog done\n", __FUNCTION__); \
+                       break;                                                                                                          \
+               }                                                                                                                               \
+       }                                                                                                                                       \
+       if (loops < max_loops) {                                                                                        \
+               diag_printf1("%s: auto_prog done after %u loops\n",                             \
+                                       __FUNCTION__, MAX_LOOPS - loops);                                       \
+               max_loops = loops;                                                                                              \
+       }                                                                                                                                       \
+       nfc_reg_write((nfc_reg_read(NFC_IPC_REG) & ~NFC_IPC_AUTO_DONE),         \
+                               NFC_IPC_REG);                                                                                   \
+       CYG_MACRO_END
+
+// Polls the NANDFC to wait for an operation to complete
+#define wait_op_done()                                                                                                 \
+       CYG_MACRO_START                                                                                                         \
+       int loops = MAX_LOOPS;                                                                                          \
+       static int max_loops = MAX_LOOPS;                                                                       \
+       while ((nfc_reg_read(NFC_IPC_REG) & NFC_IPC_INT) == 0) {                        \
+               HAL_DELAY_US(10);                                                                                               \
+               if (loops-- < 0) {                                                                                              \
+                       diag_printf("%s: Timeout waiting for NFC ready\n", __FUNCTION__); \
+                       break;                                                                                                          \
+               }                                                                                                                               \
+       }                                                                                                                                       \
+       if (loops < max_loops) {                                                                                        \
+               diag_printf1("%s: NFC ready after %u loops\n",                                  \
+                                       __FUNCTION__, MAX_LOOPS - loops);                                       \
+               max_loops = loops;                                                                                              \
+       }                                                                                                                                       \
+       nfc_reg_write(0, NFC_IPC_REG);                                                                          \
+       CYG_MACRO_END
+#else
+#define wait_for_auto_prog_done()                                                                              \
+       CYG_MACRO_START                                                                                                         \
+       while ((nfc_reg_read(NFC_IPC_REG) & NFC_IPC_AUTO_DONE) == 0) {
+       }
+       nfc_reg_write((nfc_reg_read(NFC_IPC_REG) & ~NFC_IPC_AUTO_DONE),
+                               NFC_IPC_REG);
+       CYG_MACRO_END
 
 // Polls the NANDFC to wait for an operation to complete
-#define wait_op_done()                                                                                 \
-       do {                                                                                                            \
-               while ((nfc_reg_read(NFC_IPC_REG) & NFC_IPC_INT) == 0)  \
-                       {}                                                                                                      \
-               write_nfc_ip_reg(0, NFC_IPC_REG);                                               \
-       } while (0)
+#define wait_op_done()
+       CYG_MACRO_START
+       while ((nfc_reg_read(NFC_IPC_REG) & NFC_IPC_INT) == 0) {
+       }
+       nfc_reg_write(0, NFC_IPC_REG);
+       CYG_MACRO_END
+#endif
 
-#if 0
+#if 1
+#include <cyg/hal/plf_mmap.h>
 #define nfc_reg_write(v, r)            __nfc_reg_write(v, (void *)(r), #r, __FUNCTION__)
 static inline void __nfc_reg_write(u32 val, void *addr,
                                                                   const char *reg, const char *fn)
 {
-       diag_printf1("%s: Writing %08x to %s[%04lx]\n", fn, val, reg,
-                                (unsigned long)addr & 0x1fff);
+       unsigned long pa;
+       HAL_VIRT_TO_PHYS_ADDRESS((unsigned long)addr, pa);
+       diag_printf1("%s: Writing %08x to %s[%04lx]\n", fn, val, reg, pa);
        writel(val, addr);
 }
 
@@ -133,9 +180,11 @@ static inline u32 __nfc_reg_read(void *addr,
                                                                 const char *reg, const char *fn)
 {
        u32 val;
+       unsigned long pa;
+
+       HAL_VIRT_TO_PHYS_ADDRESS((unsigned long)addr, pa);
        val = readl(addr);
-       diag_printf1("%s: Read %08x from %s[%04lx]\n", fn, val, reg,
-                                (unsigned long)addr & 0x1fff);
+       diag_printf1("%s: Read %08x from %s[%04lx]\n", fn, val, reg, pa);
        return val;
 }
 #else
@@ -145,11 +194,30 @@ static inline u32 __nfc_reg_read(void *addr,
 
 static void write_nfc_ip_reg(u32 val, u32 reg)
 {
-    nfc_reg_write(NFC_IPC_CREQ, NFC_IPC_REG);
-    while((nfc_reg_read(NFC_IPC_REG) & NFC_IPC_CACK) == 0);
+       unsigned int ipc = nfc_reg_read(NFC_IPC_REG);
+       int loops = MAX_LOOPS;
+       static int max_loops = MAX_LOOPS;
+
+       if (ipc & NFC_IPC_CACK) {
+               diag_printf("%s: IPC ACK already set!\n", __FUNCTION__);
+       } else {
+               nfc_reg_write(NFC_IPC_CREQ, NFC_IPC_REG);
+       }
 
-    nfc_reg_write(val, reg);
-    nfc_reg_write((nfc_reg_read(NFC_IPC_REG) & ~NFC_IPC_CREQ), NFC_IPC_REG);
+       while ((nfc_reg_read(NFC_IPC_REG) & NFC_IPC_CACK) == 0) {
+               HAL_DELAY_US(1);
+               if (loops-- < 0) {
+                       diag_printf("%s: Timeout waiting for IPC ready\n", __FUNCTION__);
+                       return;
+               }
+       }
+       if (loops < max_loops) {
+               diag_printf("%s: NFC ready after %u loops\n",
+                                       __FUNCTION__, MAX_LOOPS - loops);
+               max_loops = loops;
+       }
+       nfc_reg_write(val, reg);
+       nfc_reg_write((nfc_reg_read(NFC_IPC_REG) & ~NFC_IPC_CREQ), NFC_IPC_REG);
 }
 
 /*!
@@ -160,70 +228,79 @@ static void write_nfc_ip_reg(u32 val, u32 reg)
  * @param ecc_en    1 - ecc enabled; 0 - ecc disabled
  */
 static void NFC_DATA_OUTPUT(enum nfc_internal_buf buf_no, enum nfc_output_mode mode,
-                           int ecc_en)
+                                                       int ecc_en)
 {
-    u32 v = nfc_reg_read(NFC_FLASH_CONFIG2_REG);
+       u32 v = nfc_reg_read(NFC_FLASH_CONFIG2_REG);
 
-    if ((v & NFC_FLASH_CONFIG2_ECC_EN) != 0 && ecc_en == 0) {
-       write_nfc_ip_reg(v & ~NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
-    }
-    if ((v & NFC_FLASH_CONFIG2_ECC_EN) == 0 && ecc_en != 0) {
-       write_nfc_ip_reg(v | NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
-    }
+       if ((v & NFC_FLASH_CONFIG2_ECC_EN) != 0 && ecc_en == 0) {
+               write_nfc_ip_reg(v & ~NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
+       }
+       if ((v & NFC_FLASH_CONFIG2_ECC_EN) == 0 && ecc_en != 0) {
+               write_nfc_ip_reg(v | NFC_FLASH_CONFIG2_ECC_EN, NFC_FLASH_CONFIG2_REG);
+       }
 
-    v = nfc_reg_read(NAND_CONFIGURATION1_REG);
+       v = nfc_reg_read(NAND_CONFIGURATION1_REG);
 
-    if (mode == FDO_SPARE_ONLY) {
-       v = (v & ~0x71) | buf_no | NAND_CONFIGURATION1_SP_EN;
-    } else {
-       v = (v & ~0x71) | buf_no;
-    }
+       if (mode == FDO_SPARE_ONLY) {
+               v = (v & ~0x71) | buf_no | NAND_CONFIGURATION1_SP_EN;
+       } else {
+               v = (v & ~0x71) | buf_no;
+       }
 
-    nfc_reg_write(v, NAND_CONFIGURATION1_REG);
+       nfc_reg_write(v, NAND_CONFIGURATION1_REG);
 
-    nfc_reg_write(mode & 0xFF, NAND_LAUNCH_REG);
-    wait_op_done();
+       nfc_reg_write(mode & 0xFF, NAND_LAUNCH_REG);
+       wait_op_done();
 }
 
 static void NFC_CMD_INPUT(u32 cmd)
 {
-    nfc_reg_write(cmd & 0xFFFF, NAND_CMD_REG);
-    nfc_reg_write(NAND_LAUNCH_FCMD, NAND_LAUNCH_REG);
-    wait_op_done();
+       nfc_reg_write(cmd & 0xFFFF, NAND_CMD_REG);
+       nfc_reg_write(NAND_LAUNCH_FCMD, NAND_LAUNCH_REG);
+       wait_op_done();
 }
 
 static void NFC_SET_NFC_ACTIVE_CS(u32 cs_line)
 {
-    u32 v;
+       u32 v;
 
-    v = nfc_reg_read(NAND_CONFIGURATION1_REG) & (~0x7071);
-    v |= (cs_line << 12);
-    nfc_reg_write(v, NAND_CONFIGURATION1_REG);
+       v = nfc_reg_read(NAND_CONFIGURATION1_REG) & ~0x7071;
+       v |= (cs_line << 12);
+       nfc_reg_write(v, NAND_CONFIGURATION1_REG);
 }
 
-static u16 NFC_STATUS_READ(void)
+#ifdef IMX51_TO_2
+static inline u16 NFC_STATUS_READ(void)
 {
-    u32 status;
-    u16 status_sum = 0;
-    int i;
+       u16 val = nfc_reg_read(NAND_STATUS_SUM_REG);
 
-#ifdef IMX51_TO_2
-    return nfc_reg_read(NAND_STATUS_SUM_REG);
+       if (val != 0) {
+               diag_printf("NFC STATUS: %04x\n", val);
+       }
+       return val;
+}
 #else
-    /* Cannot rely on STATUS_SUM register due to errata */
-    for (i = 0; i < num_of_nand_chips; i++) {
-       NFC_SET_NFC_ACTIVE_CS(i);
-       do {
-           nfc_reg_write(NAND_LAUNCH_AUTO_STAT, NAND_LAUNCH_REG);
-           status = (nfc_reg_read(NAND_CONFIGURATION1_REG) & 0x00FF0000) >> 16;
-       } while ((status & 0x40) == 0); // make sure I/O 6 == 1
-       /* Get Pass/Fail status */
-       status = (nfc_reg_read(NAND_CONFIGURATION1_REG) >> 16) & 0x1;
-       status_sum |= (status << i);
-    }
-    return status_sum;
-#endif
+static inline u16 NFC_STATUS_READ(void)
+{
+       u32 status;
+       int i;
+       u16 status_sum = 0;
+
+       /* Cannot rely on STATUS_SUM register due to errata */
+       for (i = 0; i < num_of_nand_chips; i++) {
+               NFC_SET_NFC_ACTIVE_CS(i);
+               do {
+                       nfc_reg_write(NAND_LAUNCH_AUTO_STAT, NAND_LAUNCH_REG);
+                       status = (nfc_reg_read(NAND_CONFIGURATION1_REG) & 0x00FF0000) >> 16;
+               } while ((status & 0x40) == 0); // make sure I/O 6 == 1
+               /* Get Pass/Fail status */
+               status = (nfc_reg_read(NAND_CONFIGURATION1_REG) >> 16) & 0x1;
+               status_sum |= (status << i);
+       }
+       diag_printf("NFC TO2 STATUS: %04x\n", status_sum);
+       return status_sum;
 }
+#endif
 
 /* This function uses a global variable for the page size. It shouldn't be a big
  * problem since we don't expect mixed page size nand flash parts on the same IC.
@@ -232,104 +309,41 @@ static u16 NFC_STATUS_READ(void)
  */
 static void start_nfc_addr_ops(u32 ops, u32 pg_no, u16 pg_off, u32 is_erase, u32 cs_line, u32 num_of_chips)
 {
-    u32 add0, add8, page_number;
-    int num_of_bits[] = {0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4};
-
-    if (ops == FLASH_Read_ID) {
-       // issue addr cycle
-       nfc_reg_write(0x0, NAND_ADD0_REG + (4 * cs_line));
-       nfc_reg_write(NAND_LAUNCH_FADD, NAND_LAUNCH_REG);
-       wait_op_done();
-       return;
-    }
+       u32 add0, add8, page_number;
+       int num_of_bits[] = {0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4};
+
+       if (ops == FLASH_Read_ID) {
+               // issue addr cycle
+               nfc_reg_write(0x0, NAND_ADD0_REG + (4 * cs_line));
+               nfc_reg_write(NAND_LAUNCH_FADD, NAND_LAUNCH_REG);
+               wait_op_done();
+               return;
+       }
 
-    if (num_of_chips >  1) {
-       page_number = (pg_no << num_of_bits[num_of_chips]) | (cs_line & (num_of_chips - 1));
-    } else {
-       page_number = pg_no;
-    }
-    if (is_erase) {
-       add0 = page_number;
-       add8 = 0;
-    } else {
-       // for both read and write
-       if (g_is_2k_page || g_is_4k_page) {
-           // the first two addr cycles are for column addr. Page number starts
-           // from the 3rd addr cycle.
-           add0 = pg_off | (page_number << 16);
-           add8 = page_number >> 16;
+       if (num_of_chips >  1) {
+               page_number = (pg_no << num_of_bits[num_of_chips]) | (cs_line & (num_of_chips - 1));
        } else {
-           diag_printf("too bad, die\n");
-           asm("1: b 1b");
-           // For 512B page, the first addr cycle is for column addr. Page number
-           // starts from the 2nd addr cycle.
-           add0 = (pg_off & 0xFF) | (page_number << 8);
-           add8 = page_number >> 24;
+               page_number = pg_no;
        }
-    }
-    nfc_reg_write(add0, NAND_ADD0_REG);
-    nfc_reg_write(add8, NAND_ADD8_REG);
-}
-
-/*
- * Do a page read at random address
- *
- * @param pg_no             page number offset from 0
- * @param pg_off             byte offset within the page
- * @param ecc_force        can force ecc to be off. Otherwise, by default it is on
- *                                    unless the page offset is non-zero
- * @param cs_line            indicates which NAND of interleaved NAND devices is used
- *
- * @return  0 if successful; non-zero otherwise
- */
-static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line, u32 num_of_chips)
-{
-    u32 ecc = NFC_FLASH_CONFIG2_ECC_EN;
-    u32 v, res = 0;
-
-    // clear the NAND_STATUS_SUM_REG register
-    nfc_reg_write(0, NAND_STATUS_SUM_REG);
-
-    // the 2nd condition is to test for unaligned page address -- ecc has to be off.
-    if (ecc_force == ECC_FORCE_OFF || pg_off != 0 ) {
-       ecc = 0;
-    }
-
-    // Take care of config1 for RBA and SP_EN
-    v = nfc_reg_read(NAND_CONFIGURATION1_REG) & (~0x71);
-    nfc_reg_write(v, NAND_CONFIGURATION1_REG);
-
-    // For ECC
-    v = nfc_reg_read(NFC_FLASH_CONFIG2_REG) & (~NFC_FLASH_CONFIG2_ECC_EN);
-    // setup config2 register for ECC enable or not
-    write_nfc_ip_reg(v | ecc, NFC_FLASH_CONFIG2_REG);
-
-    start_nfc_addr_ops(FLASH_Read_Mode1, pg_no, pg_off, 0, cs_line, num_of_chips);
-
-    if (g_is_2k_page || g_is_4k_page) {
-       // combine the two commands for 2k/4k page read
-       nfc_reg_write((FLASH_Read_Mode1_LG << 8) | FLASH_Read_Mode1, NAND_CMD_REG);
-    } else {
-       // just one command is enough for 512 page
-       nfc_reg_write(FLASH_Read_Mode1, NAND_CMD_REG);
-    }
-
-    // start auto-read
-    nfc_reg_write(NAND_LAUNCH_AUTO_READ, NAND_LAUNCH_REG);
-    wait_op_done();
-
-    v = nfc_reg_read(NAND_STATUS_SUM_REG);
-    // test for CS0 ECC error from the STATUS_SUM register
-    if ((v & (0x0100 << cs_line)) != 0) {
-       // clear the status
-       nfc_reg_write((0x0100 << cs_line), NAND_STATUS_SUM_REG);
-       diag_printf("ECC error from NAND_STATUS_SUM_REG(0x%x) = 0x%x\n",
-                   NAND_STATUS_SUM_REG, v);
-       diag_printf("NAND_ECC_STATUS_RESULT_REG(0x%x) = 0x%x\n", NAND_ECC_STATUS_RESULT_REG,
-                   nfc_reg_read(NAND_ECC_STATUS_RESULT_REG));
-       res = -1;
-    }
-    return res;
+       if (is_erase) {
+               add0 = page_number;
+               add8 = 0;
+       } else {
+               // for both read and write
+               if (g_is_2k_page || g_is_4k_page) {
+                       // the first two addr cycles are for column addr. Page number starts
+                       // from the 3rd addr cycle.
+                       add0 = pg_off | (page_number << 16);
+                       add8 = page_number >> 16;
+               } else {
+                       // For 512B page, the first addr cycle is for column addr. Page number
+                       // starts from the 2nd addr cycle.
+                       add0 = (pg_off & 0xFF) | (page_number << 8);
+                       add8 = page_number >> 24;
+               }
+       }
+       nfc_reg_write(add0, NAND_ADD0_REG);
+       nfc_reg_write(add8, NAND_ADD8_REG);
 }
 
 /*!
@@ -337,7 +351,6 @@ static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line,
  */
 static void NFC_PRESET(u32 max_block_count)
 {
-    // not needed. It is done in plf_hardware_init()
+       // not needed. It is done in plf_hardware_init()
 }
-
 #endif // _MXC_NFC_V3_H_
index 2006048438477a5315aba9d87a992af01562c5c7..8e1d979bca12d1bb0bfb9b743e65ac38cc22866d 100644 (file)
@@ -57,7 +57,7 @@
 #include <cyg/infra/cyg_type.h>
 
 
-#define ESDHC_SOFTWARE_RESET   0x01000000  /* RSTA bit of ESDHC system control register*/
+#define ESDHC_SOFTWARE_RESET   0x01000000  /* RSTA bit of ESDHC system control register*/
 #define ESDHC_CMD_INHIBIT       0x00000003  /* Command inhibit bits*/
 #define ESDHC_SOFTWARE_INIT     0x08000000  /* INITA bit of ESDHC system control register */
 #define ESDHC_LITTLE_ENDIAN_MODE 0x00000020  /* Little Endian mode */
 #define ESDHC_ONE_BIT_SUPPORT    0x00000000  /* 1 Bit Mode support */
 #define ESDHC_FOUR_BIT_SUPPORT   0x00000002  /* 4 Bit Mode support */
 #define ESDHC_EIGHT_BIT_SUPPORT  0x00000004  /* 8 Bit Mode support */
-#define ESDHC_CLOCK_ENABLE             0x00000007    /* Clock Enable */
+#define ESDHC_CLOCK_ENABLE             0x00000007    /* Clock Enable */
 #define ESDHC_ENABLE                        0x00000008    /* Enable SD */
 
 #define ESDHC_FREQ_MASK 0xffff0007
 #define ESDHC_IDENT_FREQ 0x0000800e  /* SDCLKFS 0x08 ; DVS 0xe */
 #define ESDHC_OPERT_FREQ 0x00000200  /* SDCLKFS 0x02 ; DVS 0x0 */
-#define ESDHC_INTERRUPT_ENABLE         0x007f0123        /* Enable Interrupts */
+#define ESDHC_INTERRUPT_ENABLE 0x007f0123        /* Enable Interrupts */
 #define ESDHC_CONFIG_BLOCK 0x00010200             /* 512 byte block size*/
 #define ESDHC_CLEAR_INTERRUPT 0xffffffff
 
 #define ONE 1
 #define ESDHC1 0
 /*==================================================================================================
-                                             ENUS
+                                             ENUMS
 ==================================================================================================*/
 #define ESDHC_STATUS_END_CMD_RESP_MSK 0x1
 #define ESDHC_STATUS_END_CMD_RESP_TIME_MSK 0x00010001
 
 typedef enum
 {
-    WRITE = 0,
-    READ = 1,
+       WRITE = 0,
+       READ = 1,
 }xfer_type_t;
 
 typedef enum
 {
-    RESPONSE_NONE,
-    RESPONSE_136,
-    RESPONSE_48,
-    RESPONSE_48_CHECK_BUSY
+       RESPONSE_NONE,
+       RESPONSE_136,
+       RESPONSE_48,
+       RESPONSE_48_CHECK_BUSY
 }response_format_t;
 
 
 typedef enum
 {
-       DATA_PRESENT_NONE = 0,
-       DATA_PRESENT = 1
+       DATA_PRESENT_NONE = 0,
+       DATA_PRESENT = 1
 }data_present_select;
 
 typedef enum
 {
-       DISABLE = 0,
-       ENABLE = 1
+       DISABLE = 0,
+       ENABLE = 1
 }crc_check_enable,cmdindex_check_enable,block_count_enable;
 
 typedef enum
 {
        SINGLE = 0,
-       MULTIPLE = 1
+       MULTIPLE = 1
 }multi_single_block_select;
 
 typedef struct
 {
-    cyg_uint32 command;
-    cyg_uint32 arg;
-    xfer_type_t data_transfer;
-    response_format_t response_format;
-    data_present_select data_present;
-    crc_check_enable crc_check;
-    cmdindex_check_enable cmdindex_check;
+       cyg_uint32 command;
+       cyg_uint32 arg;
+       xfer_type_t data_transfer;
+       response_format_t response_format;
+       data_present_select data_present;
+       crc_check_enable crc_check;
+       cmdindex_check_enable cmdindex_check;
        block_count_enable block_count_enable_check;
        multi_single_block_select multi_single_block;
 }command_t;
 
 typedef struct
 {
-    response_format_t format;
-    cyg_uint32 cmd_rsp0;
-    cyg_uint32 cmd_rsp1;
-    cyg_uint32 cmd_rsp2;
-    cyg_uint32 cmd_rsp3;
+       response_format_t format;
+       cyg_uint32 cmd_rsp0;
+       cyg_uint32 cmd_rsp1;
+       cyg_uint32 cmd_rsp2;
+       cyg_uint32 cmd_rsp3;
 }command_response_t;
 
 typedef enum
@@ -189,8 +189,8 @@ typedef enum
 
 typedef enum
 {
-    OPERATING_FREQ = 20000,   /* in kHz */
-    IDENTIFICATION_FREQ = 400   /* in kHz */
+       OPERATING_FREQ = 20000,   /* in kHz */
+       IDENTIFICATION_FREQ = 400   /* in kHz */
 }sdhc_freq_t;
 
 
@@ -214,30 +214,30 @@ enum esdhc_reset_status
 
 typedef struct
 {
-    volatile cyg_uint32 dma_system_address;
-    volatile cyg_uint32 block_attributes;
-    volatile cyg_uint32 command_argument;
-    volatile cyg_uint32 command_transfer_type;
-    volatile cyg_uint32 command_response0;
-    volatile cyg_uint32 command_response1;
-    volatile cyg_uint32 command_response2;
-    volatile cyg_uint32 command_response3;
-    volatile cyg_uint32 data_buffer_access;
-    volatile cyg_uint32 present_state;
-    volatile cyg_uint32 protocol_control;
-    volatile cyg_uint32 system_control;
-    volatile cyg_uint32 interrupt_status;
-    volatile cyg_uint32 interrupt_status_enable;
-    volatile cyg_uint32 interrupt_signal_enable;
-    volatile cyg_uint32 autocmd12_status;
-    volatile cyg_uint32 host_controller_capabilities;
-    volatile cyg_uint32 watermark_level;
-    cyg_uint32 reserved1[2];
-    volatile cyg_uint32 force_event;
-    volatile cyg_uint32 adma_error_status_register;
-    volatile cyg_uint32 adma_system_address;
-    cyg_uint32 reserved[40];
-    volatile cyg_uint32 host_controller_version;
+       volatile cyg_uint32 dma_system_address;
+       volatile cyg_uint32 block_attributes;
+       volatile cyg_uint32 command_argument;
+       volatile cyg_uint32 command_transfer_type;
+       volatile cyg_uint32 command_response0;
+       volatile cyg_uint32 command_response1;
+       volatile cyg_uint32 command_response2;
+       volatile cyg_uint32 command_response3;
+       volatile cyg_uint32 data_buffer_access;
+       volatile cyg_uint32 present_state;
+       volatile cyg_uint32 protocol_control;
+       volatile cyg_uint32 system_control;
+       volatile cyg_uint32 interrupt_status;
+       volatile cyg_uint32 interrupt_status_enable;
+       volatile cyg_uint32 interrupt_signal_enable;
+       volatile cyg_uint32 autocmd12_status;
+       volatile cyg_uint32 host_controller_capabilities;
+       volatile cyg_uint32 watermark_level;
+       cyg_uint32 reserved1[2];
+       volatile cyg_uint32 force_event;
+       volatile cyg_uint32 adma_error_status_register;
+       volatile cyg_uint32 adma_system_address;
+       cyg_uint32 reserved[40];
+       volatile cyg_uint32 host_controller_version;
 }host_register, *host_register_ptr;
 
 
@@ -253,5 +253,6 @@ extern cyg_uint32 host_data_write(cyg_uint32 *,cyg_uint32);
 extern void host_cfg_block(cyg_uint32 blk_len, cyg_uint32 nob);
 extern void host_init(cyg_uint32 base_address);
 extern void esdhc_softreset(cyg_uint32 mask);
+extern cyg_uint32 card_get_capacity_size (void);
 /*================================================================================================*/
 #endif  /* _MXCMCI_HOST_H_ */
diff --git a/packages/devs/flash/arm/mxc/v2_0/include/tx51_nand_bbt.h b/packages/devs/flash/arm/mxc/v2_0/include/tx51_nand_bbt.h
new file mode 100644 (file)
index 0000000..e913db6
--- /dev/null
@@ -0,0 +1,25 @@
+static cyg_int8 bbt_pattern[] = {'B', 'b', 't', '0' };
+static cyg_int8 mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr tx51_bbt_main_descr = {
+       .options = (NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+                               NAND_BBT_2BIT | NAND_BBT_VERSION),
+       .offs = 0,
+       .len = 4,
+       .veroffs = 4,
+       .maxblocks = 4,
+       .pattern = bbt_pattern,
+};
+
+static struct nand_bbt_descr tx51_bbt_mirror_descr = {
+       .options = (NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+                               NAND_BBT_2BIT | NAND_BBT_VERSION),
+       .offs = 0,
+       .len = 4,
+       .veroffs = 4,
+       .maxblocks = 4,
+       .pattern = mirror_pattern,
+};
+
+static struct nand_bbt_descr *g_mxc_nfc_bbt_main_descr = &tx51_bbt_main_descr;
+static struct nand_bbt_descr *g_mxc_nfc_bbt_mirror_descr = &tx51_bbt_mirror_descr;
index 9ecd22ee8d1bd97d153f1c663328dce61672a150..118f6f92e37f3bf9284af458993ac329e3bdc431 100644 (file)
@@ -55,6 +55,7 @@
 //==========================================================================
 
 #include <pkgconf/hal.h>
+#include <cyg/infra/diag.h>
 #include <cyg/hal/hal_arch.h>
 #include <cyg/hal/hal_cache.h>
 #ifdef CYGPKG_REDBOOT_HAL_OPTIONS
@@ -80,36 +81,36 @@ int flash_hwr_init(void)
 int mmcflash_hwr_init(void)
 #endif
 {
-    cyg_uint32 status = FAIL;
-    cyg_uint32 capacity = 0;
-    int i = 5;
-    while (status != SUCCESS && i--) {
-        hal_delay_us(100000);
-        status = mxcmci_init(1, ESDHC1_REG_BASE);
-    }
-
-    if (FAIL == status) {
-        diag_printf("Error: Card initialization failed!\n");
-        return status;
-    }
-    diag_printf("Card initialization successful!\n");
-    //set flash_info structure
-    externC struct flash_info flash_info;
-    flash_dprintf(FLASH_DEBUG_MAX,"%s: status=%d\n", __FUNCTION__, status);
-    capacity = card_get_capacity_size(); // in unit of KB
-    diag_printf("Actual capacity of the card is %dKB\n", capacity);
-    //if the capacity size is larger than 2G or equals zero, force to be 2G
-    if (capacity > 0x200000 || capacity == 0) {
-        capacity = 0x200000;
-    }
-    diag_printf("Redboot uses %dKB\n", capacity);
-
-    flash_info.block_size = 0x20000; // =  128KB
-    flash_info.blocks = capacity / 128;
-    flash_info.start = (void *)MXC_MMC_BASE_DUMMY;
-    flash_info.end = (void *)(MXC_MMC_BASE_DUMMY + flash_info.block_size * flash_info.blocks);
-
-    return status;
+       cyg_uint32 status = FAIL;
+       cyg_uint32 capacity = 0;
+       int i = 5;
+       while (status != SUCCESS && i--) {
+               hal_delay_us(100000);
+               status = mxcmci_init(1, ESDHC1_REG_BASE);
+       }
+
+       if (FAIL == status) {
+               diag_printf("Error: Card initialization failed!\n");
+               return status;
+       }
+       diag_printf("Card initialization successful!\n");
+       //set flash_info structure
+       externC struct flash_info flash_info;
+       flash_dprintf(FLASH_DEBUG_MAX,"%s: status=%d\n", __FUNCTION__, status);
+       capacity = card_get_capacity_size(); // in unit of KB
+       diag_printf("Actual capacity of the card is %dKB\n", capacity);
+       //if the capacity size is larger than 2G or equals zero, force to be 2G
+       if (capacity > 0x200000 || capacity == 0) {
+               capacity = 0x200000;
+       }
+       diag_printf("Redboot uses %dKB\n", capacity);
+
+       flash_info.block_size = 0x20000; // =  128KB
+       flash_info.blocks = capacity / 128;
+       flash_info.start = (void *)MXC_MMC_BASE_DUMMY;
+       flash_info.end = (void *)(MXC_MMC_BASE_DUMMY + flash_info.block_size * flash_info.blocks);
+
+       return status;
 }
 
 
@@ -132,7 +133,7 @@ void flash_query(void* data)
 void mmcflash_query(void* data)
 #endif
 {
-    return card_flash_query(data);
+       card_flash_query(data);
 }
 
 #ifndef MXCFLASH_SELECT_MULTI
@@ -141,7 +142,7 @@ int flash_hwr_map_error(int e)
 int mmcflash_hwr_map_error(int e)
 #endif
 {
-    return e;
+       return e;
 }
 
 #ifndef MXCFLASH_SELECT_MULTI
@@ -150,14 +151,14 @@ bool flash_code_overlaps(void *start, void *end)
 bool mmcflash_code_overlaps(void *start, void *end)
 #endif
 {
-    extern char _stext[], _etext[];
-
-    bool ret = ((((unsigned long)&_stext >= (unsigned long)start) &&
-                 ((unsigned long)&_stext < (unsigned long)end)) ||
-                (((unsigned long)&_etext >= (unsigned long)start) &&
-                 ((unsigned long)&_etext < (unsigned long)end)));
-    flash_dprintf(FLASH_DEBUG_MAX,"%s: flash code overlap::%d\n", __FUNCTION__, ret);
-    return ret;
+       extern char _stext[], _etext[];
+
+       bool ret = ((((unsigned long)&_stext >= (unsigned long)start) &&
+                                                       ((unsigned long)&_stext < (unsigned long)end)) ||
+                               (((unsigned long)&_etext >= (unsigned long)start) &&
+                                       ((unsigned long)&_etext < (unsigned long)end)));
+       flash_dprintf(FLASH_DEBUG_MAX,"%s: flash code overlap::%d\n", __FUNCTION__, ret);
+       return ret;
 }
 
 #ifndef MXCFLASH_SELECT_MULTI
@@ -166,8 +167,8 @@ int flash_erase_block(void* block, unsigned int size)
 int mmcflash_erase_block(void* block, unsigned int size)
 #endif
 {
-    flash_dprintf(FLASH_DEBUG_MAX,"%s:Debug:1:block=0x%X, size=%d\n", __FUNCTION__, (cyg_uint32)block, size);
-    return mmc_data_erase((cyg_uint32)block, size);
+       flash_dprintf(FLASH_DEBUG_MAX,"%s:Debug:1:block=0x%X, size=%d\n", __FUNCTION__, (cyg_uint32)block, size);
+       return mmc_data_erase((cyg_uint32)block, size);
 }
 
 #ifndef MXCFLASH_SELECT_MULTI
index 82309b94f4943bc58baa2fe707015aa2a8a8649b..fbeffcc19f19808424e7d165a723fda2721f1014 100644 (file)
@@ -134,10 +134,9 @@ static int nfc_program_blk(u32 ra, u8 *buf, u32 len);
 static void print_pkt_16(u16 *pkt, u32 len);
 
 // globals
-static int nand_flash_index = -1;
 static int g_ecc_enable = true;
 static int g_spare_only_read_ok = true;
-static int g_nfc_debug_level = NFC_DEBUG_NONE;
+static int g_nfc_debug_level = NFC_DEBUG_DEF;
 static bool g_nfc_debug_measure = false;
 static bool g_is_2k_page = false;
 static unsigned int g_block_offset;
@@ -175,10 +174,19 @@ void nandflash_query(void *data)
 #endif
 {
        u32 id[2];
+
+       nfc_printf(NFC_DEBUG_MIN, "%s@%d data=%p\n", __FUNCTION__, __LINE__, data);
+
        read_nflash_id(&id[0], 0);
-       nfc_printf(NFC_DEBUG_MAX, "%s(ID=0x%02x: 0x%02x, 0x%02x, 0x%02x)\n", __FUNCTION__,
+       nfc_printf(NFC_DEBUG_MIN, "%s(ID=0x%02x: 0x%02x, 0x%02x, 0x%02x)\n", __FUNCTION__,
                           id[0] & 0xff, (id[0] >> 8) & 0xff, (id[0] >> 16) & 0xff, id[0] >> 24);
-       memcpy(data, id, sizeof(id));
+       if (data != NULL) {
+               nfc_printf(NFC_DEBUG_MAX, "%s@%d copy flash ID from %p to %p\n",
+                               __FUNCTION__, __LINE__, &id[0], data);
+               memcpy(data, id, sizeof(id));
+       }
+       nfc_printf(NFC_DEBUG_MAX, "%s@%d %p\n", __FUNCTION__, __LINE__,
+                       __builtin_return_address(0));
 }
 
 #ifndef MXCFLASH_SELECT_MULTI
@@ -356,7 +364,7 @@ static int flash_addr_valid(flash_addr_t addr)
 void mxc_flash_enable(void *start, void *end)
 {
        flash_addr_t s = (unsigned long)start & MXC_NAND_ADDR_MASK;
-       flash_addr_t e = (unsigned long)end & MXC_NAND_ADDR_MASK;
+       flash_addr_t e = ((unsigned long)end - 1) & MXC_NAND_ADDR_MASK;
 
        if (flash_enable++ == 0) {
                flash_region_start = s;
@@ -376,7 +384,7 @@ void mxc_flash_enable(void *start, void *end)
 void mxc_flash_disable(void *start, void *end)
 {
        flash_addr_t s = (unsigned long)start & MXC_NAND_ADDR_MASK;
-       flash_addr_t e = (unsigned long)end & MXC_NAND_ADDR_MASK;
+       flash_addr_t e = ((unsigned long)end - 1) & MXC_NAND_ADDR_MASK;
 
        if (flash_enable) {
                if (--flash_enable == 0) {
@@ -403,6 +411,9 @@ nandflash_hwr_init(void)
        u32 id[2];
        int i;
 
+#if 0
+       return FLASH_ERR_DRV_WRONG_PART;
+#endif
        nfc_printf(NFC_DEBUG_MAX, "%s()\n", __FUNCTION__);
 
        if (nfc_iomux_setup)
@@ -412,7 +423,10 @@ nandflash_hwr_init(void)
        NFC_CMD_INPUT(FLASH_Reset);
 
        // Look through table for device data
+       nfc_printf(NFC_DEBUG_MAX, "%s@%d %p\n", __FUNCTION__, __LINE__, &id[0]);
        flash_dev_query(&id[0]);
+       nfc_printf(NFC_DEBUG_MAX, "%s@%d\n", __FUNCTION__, __LINE__);
+
        flash_dev_info = supported_devices;
        for (i = 0; i < NUM_DEVICES; i++) {
                if ((flash_dev_info->device_id == (id[0] & 0xffff)) &&
@@ -421,6 +435,7 @@ nandflash_hwr_init(void)
                        break;
                flash_dev_info++;
        }
+       nfc_printf(NFC_DEBUG_MAX, "%s@%d\n", __FUNCTION__, __LINE__);
 
        // Did we find the device? If not, return error.
        if (NUM_DEVICES == i) {
@@ -429,7 +444,6 @@ nandflash_hwr_init(void)
                return FLASH_ERR_DRV_WRONG_PART;
        }
 
-       nand_flash_index = i;
        mxcnfc_init_ok = true;
 
        if (NF_PG_SZ == 2048) {
@@ -445,11 +459,13 @@ nandflash_hwr_init(void)
                           __FUNCTION__, i, NUM_DEVICES, flash_dev_info->device_id);
 
        if (nfc_setup) {
+               nfc_printf(NFC_DEBUG_MAX, "%s@%d\n", __FUNCTION__, __LINE__);
                g_nfc_version = nfc_setup(NF_PG_SZ / num_of_nand_chips, flash_dev_info->port_size,
                                                                  flash_dev_info->type, num_of_nand_chips);
        }
+       nfc_printf(NFC_DEBUG_MAX, "%s@%d\n", __FUNCTION__, __LINE__);
        diag_printf1("NFC version: %02x\n", g_nfc_version);
-       if (g_nfc_version == MXC_NFC_V3) {
+       if (g_nfc_version >= MXC_NFC_V3) {
                for (i = 2; i <= NUM_OF_CS_LINES; i++) {
                        u32 id_tmp[2];
                        read_nflash_id(&id_tmp[0], i - 1);
@@ -610,6 +626,8 @@ static void nfc_buf_write(unsigned long dst, void *src, u32 len)
        if (!nfc_verify_addr(dst, len)) {
                return;
        }
+       diag_printf1("Copying %u byte from %p..%p to flash buffer %08lx..%08lx\n",
+                               len, bp, bp + len - 1, dst, dst + len - 1);
        if (dst & 1) {
                store_byte(d, 1, *bp);
                d++;
@@ -681,9 +699,37 @@ static void read_nflash_id(u32 *id, u32 cs_line)
 {
        volatile u32 *ptr = (volatile u32*)NAND_MAIN_BUF0;
 
-    nfc_printf(NFC_DEBUG_MIN, "%s: read flash id from chip %d @ %p\n",
+       nfc_printf(NFC_DEBUG_MIN, "%s: read flash id from chip %d @ %p\n",
                           __FUNCTION__, cs_line, ptr);
+#if 0
+#if 1
+       {
+               int i;
+               const int nwords = 512 >> 2;
+
+               for (i = 0; i < 8; i++) {
+                       int j;
+
+                       for (j = 0; j < nwords; j++) {
+                               ptr[i * nwords + j] = 0xdeadbeef;
+                       }
+               }
+       }
+#else
+       {
+               int i;
+               const int nwords = 512 >> 2;
+
+               for (i = 0; i < 8; i++) {
+                       int j;
 
+                       for (j = 0; j < nwords; j++) {
+                               id[i * nwords + j] = 0xdeadbeef;
+                       }
+               }
+       }
+#endif
+#endif
        NFC_PRESET(MXC_UNLOCK_BLK_END);
        NFC_SET_NFC_ACTIVE_CS(cs_line);
        NFC_CMD_INPUT(FLASH_Read_ID);
@@ -691,15 +737,15 @@ static void read_nflash_id(u32 *id, u32 cs_line)
        start_nfc_addr_ops(FLASH_Read_ID, 0, 0, 0, cs_line, num_of_nand_chips);
        NFC_DATA_OUTPUT(RAM_BUF_0, FDO_FLASH_ID, g_ecc_enable);
 
-    *id++ = *ptr++;
-    *id++ = *ptr++;
+       *id++ = *ptr++;
+       *id++ = *ptr++;
 }
 
 static void mark_blk_bad(unsigned int block, unsigned char *buf,
                                                 enum blk_bad_type bad_type)
 {
-       unsigned int off = block >> 2;           // byte offset - each byte can hold status for 4 blocks
-       unsigned int sft = (block & 3) << 1;  // bit shift 0, 2, 4, 6
+       unsigned int off = block >> 2;                  // byte offset - each byte can hold status for 4 blocks
+       unsigned int sft = (block & 3) << 1;    // bit shift 0, 2, 4, 6
        unsigned char val = buf[off];
 
        if (block > NF_BLK_CNT) {
@@ -980,15 +1026,15 @@ static int nfc_erase_blk(u32 ra)
        u16 flash_status, i;
        u32 pg_no, pg_off;
 
-       if (g_nfc_version == MXC_NFC_V3) {
+       if (g_nfc_version >= MXC_NFC_V3) {
                // combine the two commands for erase
-               writel((FLASH_Start_Erase << 8) | FLASH_Block_Erase, NAND_CMD_REG);
+               nfc_reg_write((FLASH_Start_Erase << 8) | FLASH_Block_Erase, NAND_CMD_REG);
                pg_no = ra / NF_PG_SZ;
                pg_off = ra % NF_PG_SZ;
                for (i = 0; i < num_of_nand_chips; i++) {
                        start_nfc_addr_ops(FLASH_Block_Erase, pg_no, pg_off, 1, i, num_of_nand_chips);
                        // start auto-erase
-                       writel(NAND_LAUNCH_AUTO_ERASE, NAND_LAUNCH_REG);
+                       nfc_reg_write(NAND_LAUNCH_AUTO_ERASE, NAND_LAUNCH_REG);
                        wait_op_done();
                        pg_off = 0;
                }
@@ -1042,7 +1088,11 @@ static int nfc_program_blk(u32 ra, u8 *buf, u32 len)
                buf += NF_PG_SZ;
        }
        if (len != 0) {
+               diag_printf1("Clearing flash buffer from %p..%p\n", g_page_buf + len - 1,
+                                       g_page_buf + NF_PG_SZ - 1);
                memset(g_page_buf + len, 0xFF, NF_PG_SZ - len);
+               diag_printf1("Copying partial page from %p..%p to %p..%p\n",
+                                       buf, buf + len - 1, g_page_buf, g_page_buf + len);
                memcpy(g_page_buf, buf, len);
                if (nfc_write_pg_random(ra / NF_PG_SZ, ra % NF_PG_SZ, g_page_buf, 0) != 0) {
                        num_of_nand_chips = temp;
@@ -1092,7 +1142,7 @@ static int nfc_erase_region(flash_addr_t addr, u32 len, bool skip_bad, bool verb
                }
                if (nfc_erase_blk(addr) != 0) {
                        diag_printf("\n** Error: Failed to erase block %u at addr 0x%08llx\n",
-                                           blk, (u64)addr);
+                                               blk, (u64)addr);
                        mark_blk_bad(blk, g_bbt, BLK_BAD_RUNTIME);
                        // we don't need to update the table immediately here since even
                        // with power loss now, we should see the same erase error again.
@@ -1293,11 +1343,21 @@ static int nfc_write_pg_random(u32 pg_no, u32 pg_off, u8 *buf, u32 ecc_force)
        }
 
        diag_printf1("%s(0x%x, 0x%x, %d)\n", __FUNCTION__, pg_no, pg_off, ecc_force);
+       if (g_nfc_version != MXC_NFC_V1) {
+               int i;
 
-       switch (g_nfc_version & 0xf0) {
-       case MXC_NFC_V3:
+               for (i = 1; i < NFC_SPARE_BUF_SZ / 16; i++) {
+                       memcpy((void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ),
+                               (void *)(NAND_SPAR_BUF0 + i * 16), 16);
+               }
+       }
+       if (g_nfc_version >= MXC_NFC_V3) {
                /* Check if Page size is greater than NFC buffer */
                do {
+                       rba = nfc_reg_read(NAND_CONFIGURATION1_REG);
+                       if ((rba >> 4) & 0x7) {
+                               nfc_reg_write(rba & ~0x70, NAND_CONFIGURATION1_REG);
+                       }
                        if (write_count <= NFC_BUFSIZE) {
                                // No need to worry about the spare area
                                nfc_buf_write(NAND_MAIN_BUF0, buf, write_count);
@@ -1309,7 +1369,7 @@ static int nfc_write_pg_random(u32 pg_no, u32 pg_off, u8 *buf, u32 ecc_force)
                                buf += NFC_BUFSIZE;
                        }
                        // combine the two commands for program
-                       writel((FLASH_Program << 8) | FLASH_Send_Data, NAND_CMD_REG);
+                       nfc_reg_write((FLASH_Program << 8) | FLASH_Send_Data, NAND_CMD_REG);
 
                        for (i = start_point; i < num_of_nand_chips; i++) {
                                rba = rba_count * ((NF_PG_SZ / num_of_nand_chips) / 512);
@@ -1320,38 +1380,30 @@ static int nfc_write_pg_random(u32 pg_no, u32 pg_off, u8 *buf, u32 ecc_force)
                                }
 
                                // For ECC
-                               v = readl(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
+                               v = nfc_reg_read(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
                                // setup config2 register for ECC enable or not
                                write_nfc_ip_reg(v | ecc, NFC_FLASH_CONFIG2_REG);
 
                                start_nfc_addr_ops(FLASH_Program, pg_no, pg_off, 0, i, num_of_nand_chips);
 
                                // start auto-program
-                               writel(NAND_LAUNCH_AUTO_PROG, NAND_LAUNCH_REG);
+                               nfc_reg_write(NAND_LAUNCH_AUTO_PROG, NAND_LAUNCH_REG);
                                if (i < (num_of_nand_chips - i))
                                        wait_for_auto_prog_done();
                                else
                                        wait_op_done();
                                pg_off = 0;
                                rba_count++;
+                               rba = nfc_reg_read(NAND_CONFIGURATION1_REG);
+                       }
+                       flash_status = NFC_STATUS_READ();
+                       // check I/O bit 0 to see if it is 0 for success
+                       if ((flash_status & ((0x1 << num_of_nand_chips) - 1)) != 0) {
+                               return -1;
                        }
                        start_point = i;
                } while (write_count > 0);
-               flash_status = NFC_STATUS_READ();
-               // check I/O bit 0 to see if it is 0 for success
-               if ((flash_status & ((0x1 << num_of_nand_chips) - 1)) != 0) {
-                       return -1;
-               }
-               break;
-       default:
-               if (g_nfc_version != MXC_NFC_V1) {
-                       int i;
-
-                       for (i = 1; i < NFC_SPARE_BUF_SZ / 16; i++) {
-                               memcpy((void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ),
-                                          (void *)(NAND_SPAR_BUF0 + i * 16), 16);
-                       }
-               }
+       } else {
                nfc_buf_write(NAND_MAIN_BUF0, buf, NF_PG_SZ);
 #ifdef BARKER_CODE_SWAP_LOC
                // To replace the data at offset MXC_NAND_BOOT_LOAD_BARKER with
@@ -1359,9 +1411,9 @@ static int nfc_write_pg_random(u32 pg_no, u32 pg_off, u8 *buf, u32 ecc_force)
                if (pg_no == 0) {
                        diag_printf("\n[INFO]: copy data at 0x%x to spare area and set it to 0x%x\n",
                                                BARKER_CODE_SWAP_LOC, BARKER_CODE_VAL);
-                       writel(readl(NFC_BASE + BARKER_CODE_SWAP_LOC), NAND_SPAR_BUF0);
+                       nfc_reg_write(nfc_reg_read(NFC_BASE + BARKER_CODE_SWAP_LOC), NAND_SPAR_BUF0);
                        // todo: set BARKER_CODE_VAL and BARKER_CODE_SWAP_LOC for skye, etc.
-                       writel(BARKER_CODE_VAL, NFC_BASE + BARKER_CODE_SWAP_LOC);
+                       nfc_reg_write(BARKER_CODE_VAL, NFC_BASE + BARKER_CODE_SWAP_LOC);
                }
 #endif
                NFC_CMD_INPUT(FLASH_Send_Data);
@@ -1390,7 +1442,73 @@ static int nfc_write_pg_random(u32 pg_no, u32 pg_off, u8 *buf, u32 ecc_force)
        return 0;
 }
 
-#ifndef NFC_V3_0
+#ifdef NFC_V3_0
+/*
+ * Do a page read at random address
+ *
+ * @param pg_no             page number offset from 0
+ * @param pg_off             byte offset within the page
+ * @param ecc_force        can force ecc to be off. Otherwise, by default it is on
+ *                                    unless the page offset is non-zero
+ * @param cs_line            indicates which NAND of interleaved NAND devices is used
+ *
+ * @return  0 if successful; non-zero otherwise
+ */
+static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line, u32 num_of_chips)
+{
+       u32 ecc = NFC_FLASH_CONFIG2_ECC_EN;
+       u32 v, res = 0;
+       int i;
+
+       // clear the NAND_STATUS_SUM_REG register
+       nfc_reg_write(0, NAND_STATUS_SUM_REG);
+
+       // the 2nd condition is to test for unaligned page address -- ecc has to be off.
+       if (ecc_force == ECC_FORCE_OFF || pg_off != 0 ) {
+               ecc = 0;
+       }
+
+       // Take care of config1 for RBA and SP_EN
+       v = nfc_reg_read(NAND_CONFIGURATION1_REG) & ~0x71;
+       nfc_reg_write(v, NAND_CONFIGURATION1_REG);
+
+       // For ECC
+       v = nfc_reg_read(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
+       // setup config2 register for ECC enable or not
+       write_nfc_ip_reg(v | ecc, NFC_FLASH_CONFIG2_REG);
+
+       start_nfc_addr_ops(FLASH_Read_Mode1, pg_no, pg_off, 0, cs_line, num_of_chips);
+
+       if (g_is_2k_page || g_is_4k_page) {
+               // combine the two commands for 2k/4k page read
+               nfc_reg_write((FLASH_Read_Mode1_LG << 8) | FLASH_Read_Mode1, NAND_CMD_REG);
+       } else {
+               // just one command is enough for 512 page
+               nfc_reg_write(FLASH_Read_Mode1, NAND_CMD_REG);
+       }
+
+       // start auto-read
+       nfc_reg_write(NAND_LAUNCH_AUTO_READ, NAND_LAUNCH_REG);
+       wait_op_done();
+
+       for (i = 1; i < NFC_SPARE_BUF_SZ / 16; i++) {
+               memcpy((void *)(NAND_SPAR_BUF0 + i * 16),
+                       (void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ), 16);
+       }
+       v = nfc_reg_read(NAND_STATUS_SUM_REG);
+       // test for CS0 ECC error from the STATUS_SUM register
+       if ((v & (0x0100 << cs_line)) != 0) {
+               // clear the status
+               nfc_reg_write(v & ~(0x0100 << cs_line), NAND_STATUS_SUM_REG);
+               diag_printf("ECC error from NAND_STATUS_SUM_REG(0x%08lx) = 0x%08x\n",
+                                       NAND_STATUS_SUM_REG, v);
+               diag_printf("NAND_ECC_STATUS_RESULT_REG(0x%08lx) = 0x%08x\n", NAND_ECC_STATUS_RESULT_REG,
+                                       nfc_reg_read(NAND_ECC_STATUS_RESULT_REG));
+               res = -1;
+       }
+       return res;
+}
+#else
 // for version V1 and V2 of NFC
 static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line,
                                                          u32 num_of_nand_chips)
@@ -1440,7 +1558,7 @@ static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line,
                        NFC_DATA_OUTPUT(RAM_BUF_3, FDO_PAGE_SPARE, ecc);
                }
                if (ecc) {
-                       t1 = readl(ECC_STATUS_RESULT_REG);
+                       t1 = nfc_reg_read(ECC_STATUS_RESULT_REG);
                        if (g_is_2k_page || g_is_4k_page) {
                                t2 = (t1 >> 4) & 0xF;
                                t3 = (t1 >> 8) & 0xF;
@@ -1480,7 +1598,7 @@ static int nfc_read_pg_random(u32 pg_no, u32 pg_off, u32 ecc_force, u32 cs_line,
        // This is needed for certain platforms
        if (pg_no == 0) {
                diag_printf("\n[INFO]: copy back data from spare to 0x%x\n", BARKER_CODE_SWAP_LOC);
-               writel(readl(NAND_SPAR_BUF0), NFC_BASE + BARKER_CODE_SWAP_LOC);
+               nfc_reg_write(nfc_reg_read(NAND_SPAR_BUF0), NFC_BASE + BARKER_CODE_SWAP_LOC);
        }
 #endif
 
@@ -1515,13 +1633,25 @@ static int nfc_write_page(u32 pg_no, u32 pg_off, u32 ecc_force)
                ecc = 0;
        }
 
+       if (g_nfc_version != MXC_NFC_V1) {
+               int i;
+
+               for (i = NFC_SPARE_BUF_SZ / 16 - 1; i >= 0; i--) {
+                       memcpy((void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ),
+                               (void *)(NAND_SPAR_BUF0 + i * 16), 16);
+               }
+       }
        if (g_nfc_version == MXC_NFC_V3) {
                int i;
                u32 v;
                u32 start_point = 0, rba, rba_count = 0;
 
+               rba = nfc_reg_read(NAND_CONFIGURATION1_REG);
+               if ((rba >> 4) & 0x7) {
+                       nfc_reg_write(rba & ~0x70, NAND_CONFIGURATION1_REG);
+               }
                // combine the two commands for program
-               writel((FLASH_Program << 8) | FLASH_Send_Data, NAND_CMD_REG);
+               nfc_reg_write((FLASH_Program << 8) | FLASH_Send_Data, NAND_CMD_REG);
 
                for (i = start_point; i < num_of_nand_chips; i++) {
                        rba = rba_count * ((NF_PG_SZ / num_of_nand_chips) / 512);
@@ -1532,14 +1662,14 @@ static int nfc_write_page(u32 pg_no, u32 pg_off, u32 ecc_force)
                        }
 
                        // For ECC
-                       v = readl(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
+                       v = nfc_reg_read(NFC_FLASH_CONFIG2_REG) & ~NFC_FLASH_CONFIG2_ECC_EN;
                        // setup config2 register for ECC enable or not
                        write_nfc_ip_reg(v | ecc, NFC_FLASH_CONFIG2_REG);
 
                        start_nfc_addr_ops(FLASH_Program, pg_no, pg_off, 0, i, num_of_nand_chips);
 
                        // start auto-program
-                       writel(NAND_LAUNCH_AUTO_PROG, NAND_LAUNCH_REG);
+                       nfc_reg_write(NAND_LAUNCH_AUTO_PROG, NAND_LAUNCH_REG);
                        if (i < (num_of_nand_chips - i))
                                wait_for_auto_prog_done();
                        else
@@ -1547,17 +1677,14 @@ static int nfc_write_page(u32 pg_no, u32 pg_off, u32 ecc_force)
                        pg_off = 0;
                        rba_count++;
                }
-               start_point = i;
                flash_status = NFC_STATUS_READ();
-       } else {
-               if (g_nfc_version != MXC_NFC_V1) {
-                       int i;
-
-                       for (i = NFC_SPARE_BUF_SZ / 16 - 1; i >= 0; i--) {
-                               memcpy((void *)(NAND_SPAR_BUF0 + i * NFC_SPARE_BUF_SZ),
-                                          (void *)(NAND_SPAR_BUF0 + i * 16), 16);
-                       }
+               // check I/O bit 0 to see if it is 0 for success
+               if ((flash_status & ((0x1 << num_of_nand_chips) - 1)) != 0) {
+                       return -1;
                }
+               rba = nfc_reg_read(NAND_CONFIGURATION1_REG);
+               start_point = i;
+       } else {
                NFC_CMD_INPUT(FLASH_Send_Data);
                start_nfc_addr_ops(FLASH_Program, pg_no, pg_off, 0, 0, num_of_nand_chips);
 
@@ -1574,11 +1701,11 @@ static int nfc_write_page(u32 pg_no, u32 pg_off, u32 ecc_force)
                NFC_CMD_INPUT(FLASH_Program);
 
                flash_status = NFC_STATUS_READ();
-       }
-       if ((flash_status & 0x1) != 0) {
-               diag_printf("** Error: failed to program page %u at addr 0x%08llx\n",
-                                       pg_no, (u64)pg_no * NF_PG_SZ + pg_off);
-               return -1;
+               if ((flash_status & 0x1) != 0) {
+                       diag_printf("** Error: failed to program page %u at addr 0x%08llx\n",
+                                               pg_no, (u64)pg_no * NF_PG_SZ + pg_off);
+                       return -1;
+               }
        }
        return 0;
 }
@@ -2161,6 +2288,8 @@ static void nand_erase(int argc, char *argv[])
                return;
        }
 
+       diag_printf1("Enabling flash from %p..%p\n", (u8 *)ra, (u8 *)ra + len - 1);
+       FLASH_Enable((u8 *)ra, (u8 *)ra + len);
        if (force_erase_set == true) {
                diag_printf("Force erase ...");
                nfc_erase_region(ra, len, 0, 1);
@@ -2168,6 +2297,7 @@ static void nand_erase(int argc, char *argv[])
        } else {
                nfc_erase_region(ra, len, 1, 1);
        }
+       FLASH_Disable((u8 *)ra, (u8 *)ra + len);
        diag_printf("\n");
 }
 
@@ -2227,11 +2357,6 @@ static void nand_info(int argc, char *argv[])
 {
        u32 i, j = 0;
 
-       if (nand_flash_index == -1) {
-               diag_printf("Can't find valid NAND flash: %d\n", __LINE__);
-               return;
-       }
-
        diag_printf("\nType:\t\t %s\n", NF_VEND_INFO);
        diag_printf("Total size:\t 0x%08x bytes (%d MiB)\n", NF_DEV_SZ, NF_DEV_SZ / SZ_1M);
        diag_printf("Total blocks:\t 0x%x (%d)\n", NF_BLK_CNT, NF_BLK_CNT);
@@ -2322,14 +2447,35 @@ static void nand_bad(int argc, char *argv[])
 static void do_nand_cmds(int argc, char *argv[])
 {
        struct cmd *cmd;
+#if 0
+       unsigned long ctrl, l2, sid, cs;
+       unsigned int d, i;
+
+       HAL_FLASH_CACHES_OFF(d, i);
+       diag_printf("DCACHE: %d ICACHE: %d\n", d, i);
+       HAL_FLASH_CACHES_ON(d, i);
+
+       asm volatile(
+               "MRC p15, 0, %0, c1, c0, 0;"
+               "MRC p15, 0, %1, c1, c0, 1;"
+               "MRC p15, 1, %2, c0, c0, 7;"
+               "MRC p15, 1, %3, c0, c0, 0;"
+               : "=r"(ctrl), "=r"(l2), "=r"(sid), "=r"(cs)
+               );
+
+       diag_printf("ctrl: %08lx aux: %08lx sid: %08lx cs: %08lx\n", ctrl, l2, sid, cs);
+#endif
 
        if (!mxcnfc_init_ok) {
+               flash_hwr_init();
+               if (!mxcnfc_init_ok) {
 #ifdef CYGHWR_DEVS_FLASH_MXC_MULTI
-               diag_printf("Warning: NAND flash hasn't been initialized. Try \"factive nand\" first\n\n");
+                       diag_printf("Warning: NAND flash hasn't been initialized. Try \"factive nand\" first\n\n");
 #else
-               diag_printf("Error: NAND flash hasn't been initialized\n");
+                       diag_printf("Error: NAND flash hasn't been initialized\n");
 #endif
-               return;
+                       return;
+               }
        }
 
        if (argc < 2) {
index 56b7e41ff65c0c517f112555d6ec256820752569..43d1fb625a9c41591fb634c4f363b3bf1fe2b540 100644 (file)
 //
 //==========================================================================
 
+#include <cyg/infra/diag.h>
 #include <cyg/io/mxcmci_host.h>
 #include <cyg/io/mxcmci_core.h>
 #include <cyg/io/mxcmci_mmc.h>
 #include <cyg/hal/hal_soc.h>
 #include <cyg/io/mxc_mmc.h>
 
-static cyg_uint32 csd_get_value(cyg_uint32 * pcsd, cyg_uint32 start_bit,
-                cyg_uint32 end_bit);
+static cyg_uint32 csd_get_value(void *csd, cyg_uint32 start_bit,
+                                                               cyg_uint32 end_bit);
 
 #define MMCSD_INIT_DELAY 64
 
@@ -78,64 +79,64 @@ int HighCapacityCard = 0;
 
 cyg_uint32 mxcmci_init(cyg_uint32 bus_width, cyg_uint32 base_address)
 {
-    cyg_uint32 init_status = FAIL;
-
-    flash_dprintf(FLASH_DEBUG_MAX, "%s:try to init base address...\n",
-              __FUNCTION__);
-    /* initialize Interface Controller */
-    host_init(base_address);
-    flash_dprintf(FLASH_DEBUG_MAX, "%s:try to software reset...\n",
-              __FUNCTION__);
-
-    /* Software Reset to Interface Controller */
-    host_reset(ESDHC_ONE_BIT_SUPPORT, ESDHC_LITTLE_ENDIAN_MODE);
-    flash_dprintf(FLASH_DEBUG_MAX, "%s:try to set identification freq...\n",
-              __FUNCTION__);
-
-    /* Enable Identification Frequency */
-    host_cfg_clock(IDENTIFICATION_FREQ);
-
-    /* Add delay of 2 msec, let mmc/sd card to initialize */
-    hal_delay_us(2 * 1000);
-
-    flash_dprintf(FLASH_DEBUG_MAX, "%s:try to software resetto card...\n",
-              __FUNCTION__);
-
-    //diag_printf("SW Reset...\n");
-    /* Issue Software Reset to card */
-    if (mxcmci_software_reset())
-        return FAIL;
-
-    //diag_printf("Check Card...\n");
-
-    /* Check if the card is SD Memory Card */
-    if (!sd_voltage_validation()) {
-        flash_dprintf(FLASH_DEBUG_MAX, "%s:try to verify SD card...\n",
-                  __FUNCTION__);
-        /* Call SD Initialization Function */
-        init_status = sd_init(bus_width);
-        Card_type =
-            ((csd.csd3 & CSD_STRUCT_MSK) ? SD_CSD_2_0 : SD_CSD_1_0);
-        Card_Mode = 1;
-        /* Card Command Class */
-        CCC = csd_get_value(&csd, 84, 95);
-    } else {
-        flash_dprintf(FLASH_DEBUG_MAX, "%s:try to verify MMC card...\n",
-                  __FUNCTION__);
-        /* Check if the card is MMC Memory Card */
-        if (!mmc_voltage_validation()) {
-
-            /* Call MMC Initialization Function */
-            init_status = mmc_init(bus_width);
-            Card_Mode = 0;
-            Card_type = ((csd.csd3 & CSD_STRUCT_MSK) >> CSD_STRUCT_SHIFT) + SD_CSD_2_0;
-            MMC_Spec_vers = (csd.csd3 & MMC_CSD_SPEC_VERS_MASK) >> MMC_CSD_SPEC_VERS_SHIFT;
-            /* Card Command Class */
-            CCC = csd_get_value(&csd, 84, 95);
-        }
-    }
-
-    return init_status;
+       cyg_uint32 init_status = FAIL;
+
+       flash_dprintf(FLASH_DEBUG_MAX, "%s:try to init base address...\n",
+                               __FUNCTION__);
+       /* initialize Interface Controller */
+       host_init(base_address);
+       flash_dprintf(FLASH_DEBUG_MAX, "%s:try to software reset...\n",
+                               __FUNCTION__);
+
+       /* Software Reset to Interface Controller */
+       host_reset(ESDHC_ONE_BIT_SUPPORT, ESDHC_LITTLE_ENDIAN_MODE);
+       flash_dprintf(FLASH_DEBUG_MAX, "%s:try to set identification freq...\n",
+                               __FUNCTION__);
+
+       /* Enable Identification Frequency */
+       host_cfg_clock(IDENTIFICATION_FREQ);
+
+       /* Add delay of 2 msec, let mmc/sd card to initialize */
+       hal_delay_us(2 * 1000);
+
+       flash_dprintf(FLASH_DEBUG_MAX, "%s:try to software resetto card...\n",
+                               __FUNCTION__);
+
+       //diag_printf("SW Reset...\n");
+       /* Issue Software Reset to card */
+       if (mxcmci_software_reset())
+               return FAIL;
+
+       //diag_printf("Check Card...\n");
+
+       /* Check if the card is SD Memory Card */
+       if (!sd_voltage_validation()) {
+               flash_dprintf(FLASH_DEBUG_MAX, "%s:try to verify SD card...\n",
+                                       __FUNCTION__);
+               /* Call SD Initialization Function */
+               init_status = sd_init(bus_width);
+               Card_type =
+                       ((csd.csd3 & CSD_STRUCT_MSK) ? SD_CSD_2_0 : SD_CSD_1_0);
+               Card_Mode = 1;
+               /* Card Command Class */
+               CCC = csd_get_value(&csd, 84, 95);
+       } else {
+               flash_dprintf(FLASH_DEBUG_MAX, "%s:try to verify MMC card...\n",
+                                       __FUNCTION__);
+               /* Check if the card is MMC Memory Card */
+               if (!mmc_voltage_validation()) {
+
+                       /* Call MMC Initialization Function */
+                       init_status = mmc_init(bus_width);
+                       Card_Mode = 0;
+                       Card_type = ((csd.csd3 & CSD_STRUCT_MSK) >> CSD_STRUCT_SHIFT) + SD_CSD_2_0;
+                       MMC_Spec_vers = (csd.csd3 & MMC_CSD_SPEC_VERS_MASK) >> MMC_CSD_SPEC_VERS_SHIFT;
+                       /* Card Command Class */
+                       CCC = csd_get_value(&csd, 84, 95);
+               }
+       }
+
+       return init_status;
 }
 
 /*==========================================================================
@@ -196,44 +197,45 @@ cyg_uint32 card_get_csd(void)
 
 }
 
-static cyg_uint32 csd_get_value(cyg_uint32 * pcsd, cyg_uint32 start_bit,
-                cyg_uint32 end_bit)
+static cyg_uint32 csd_get_value(void *csd, cyg_uint32 start_bit,
+                                                               cyg_uint32 end_bit)
 {
-    cyg_uint32 index = (start_bit / 32);
-    cyg_uint32 end_index = (end_bit / 32);
-    cyg_uint32 offset = (start_bit - 8) % 32;
-    cyg_uint32 end_offset = (end_bit - 8) % 32;
-    cyg_uint32 value;
-    cyg_uint32 temp;
-    //pcsd = &(csd.csd0);
-    flash_dprintf(FLASH_DEBUG_MAX,
-              "start_bit=%d, end_bit=%d, index=%d, end_index=%d, offset=%d\n",
-              start_bit, end_bit, index, end_index, offset);
-
-    if (index == end_index) {
-        flash_dprintf(FLASH_DEBUG_MAX, "onl1y in index register\n");
-        value =
-            (*((cyg_uint32 *) ((cyg_uint32) pcsd + (index << 2)))) &
-            ((1 << (end_offset + 1)) - (1 << offset));
-        value = (value >> offset);
-    } else {
-        flash_dprintf(FLASH_DEBUG_MAX, "index and index+1 registers\n");
-        value =
-            *((cyg_uint32 *) ((cyg_uint32) pcsd +
-                      (index << 2))) & (0xFFFFFFFF -
-                            (1 << offset) + 1);
-        value = (value >> offset);
-        temp = (1 << (offset + end_bit - start_bit - 31)) - 1;
-        temp =
-            (*((cyg_uint32 *) ((cyg_uint32) pcsd + (index + 1) * 4)) &
-             temp);
-        value += temp << (32 - offset);
-    }
-
-    flash_dprintf(FLASH_DEBUG_MAX, "%s:value=%x (CSD:%x:%x:%x:%x)\n",
-              __FUNCTION__, value, *pcsd, *(pcsd + 1), *(pcsd + 2),
-              *(pcsd + 3));
-    return value;
+       cyg_uint32 index = (start_bit / 32);
+       cyg_uint32 end_index = (end_bit / 32);
+       cyg_uint32 offset = (start_bit - 8) % 32;
+       cyg_uint32 end_offset = (end_bit - 8) % 32;
+       cyg_uint32 value;
+       cyg_uint32 temp;
+       cyg_uint32 *pcsd = csd;
+
+       flash_dprintf(FLASH_DEBUG_MAX,
+                               "start_bit=%d, end_bit=%d, index=%d, end_index=%d, offset=%d\n",
+                               start_bit, end_bit, index, end_index, offset);
+
+       if (index == end_index) {
+               flash_dprintf(FLASH_DEBUG_MAX, "onl1y in index register\n");
+               value =
+                       (*((cyg_uint32 *) ((cyg_uint32) pcsd + (index << 2)))) &
+                       ((1 << (end_offset + 1)) - (1 << offset));
+               value = (value >> offset);
+       } else {
+               flash_dprintf(FLASH_DEBUG_MAX, "index and index+1 registers\n");
+               value =
+                       *((cyg_uint32 *) ((cyg_uint32) pcsd +
+                                                               (index << 2))) & (0xFFFFFFFF -
+                                                                                               (1 << offset) + 1);
+               value = (value >> offset);
+               temp = (1 << (offset + end_bit - start_bit - 31)) - 1;
+               temp =
+                       (*((cyg_uint32 *) ((cyg_uint32) pcsd + (index + 1) * 4)) &
+                               temp);
+               value += temp << (32 - offset);
+       }
+
+       flash_dprintf(FLASH_DEBUG_MAX, "%s:value=%x (CSD:%x:%x:%x:%x)\n",
+                               __FUNCTION__, value, *pcsd, *(pcsd + 1), *(pcsd + 2),
+                               *(pcsd + 3));
+       return value;
 
 }
 
@@ -251,7 +253,7 @@ cyg_uint32 card_get_capacity_size(void)
     case MMC_CSD_1_0:
     case MMC_CSD_1_1:
     case MMC_CSD_1_2:
-        c_size = csd_get_value(&csd, 62, 73);
+               c_size = csd_get_value((void*)&csd, 62, 73);
         c_size_mult = csd_get_value(&csd, 47, 49);
         blk_len = csd_get_value(&csd, 80, 83);
         capacity = (c_size + 1) << (c_size_mult + 2 + blk_len - 10);
index 04b5ea1dfda714eb0465173296e62047ea5f1f15..07e5133e92e3f26942d33d4c534be49c64423b8d 100644 (file)
@@ -51,6 +51,7 @@
 //
 //==========================================================================
 
+#include <cyg/infra/diag.h>
 #include <cyg/io/mxcmci_host.h>
 #include <cyg/io/mxcmci_core.h>
 #include <cyg/io/mxcmci_mmc.h>
@@ -104,21 +105,21 @@ void host_reset(cyg_uint32 data_transfer_width, cyg_uint32 endian_mode)
 
 void esdhc_softreset(cyg_uint32 mask)
 {
-    //wait max timeout 100ms
-    cyg_uint32 timeout = 100;
-
-    esdhc_base_pointer->system_control |= mask;
-
-    /* hw clears the bit when it's done */
-    while (esdhc_base_pointer->system_control & mask) {
-        if (timeout == 0) {
-            flash_dprintf(FLASH_DEBUG_MAX,
-                      "%s:Reset 0x%X never complete!\n");
-            return;
-        }
-        timeout--;
-        hal_delay_us(100);
-    }
+       //wait max timeout 100ms
+       cyg_uint32 timeout = 100;
+
+       esdhc_base_pointer->system_control |= mask;
+
+       /* hw clears the bit when it's done */
+       while (esdhc_base_pointer->system_control & mask) {
+               if (timeout == 0) {
+                       flash_dprintf(FLASH_DEBUG_MAX, "%s: Reset did not complete\n",
+                                               __FUNCTION__);
+                       return;
+               }
+               timeout--;
+               hal_delay_us(100);
+       }
 }
 
 void host_init(cyg_uint32 base_address)
@@ -167,189 +168,181 @@ void host_cfg_clock(sdhc_freq_t frequency)
 
 static void esdhc_set_data_transfer_width(cyg_uint32 data_transfer_width)
 {
-
-    /* Set DWT bit of protocol control register according to bus_width */
-    esdhc_base_pointer->protocol_control &= ~0x6;
-    esdhc_base_pointer->protocol_control |= data_transfer_width;
-
+       /* Set DWT bit of protocol control register according to bus_width */
+       esdhc_base_pointer->protocol_control &= ~0x6;
+       esdhc_base_pointer->protocol_control |= data_transfer_width;
 }
 
 static void esdhc_set_endianness(cyg_uint32 endian_mode)
 {
-
-    /* Set DWT bit of protocol control register according to bus_width */
-    esdhc_base_pointer->protocol_control |= endian_mode;
-
+       /* Set DWT bit of protocol control register according to bus_width */
+       esdhc_base_pointer->protocol_control |= endian_mode;
 }
 
 cyg_uint32 host_send_cmd(command_t * cmd)
 {
 
-    /* Clear Interrupt status register */
-    esdhc_base_pointer->interrupt_status = ESDHC_CLEAR_INTERRUPT;
-    //esdhc_base_pointer->interrupt_status = 0x117f01ff;
+       /* Clear Interrupt status register */
+       esdhc_base_pointer->interrupt_status = ESDHC_CLEAR_INTERRUPT;
+       //esdhc_base_pointer->interrupt_status = 0x117f01ff;
 
-    /* Enable Interrupt */
-    esdhc_base_pointer->interrupt_status_enable |= ESDHC_INTERRUPT_ENABLE;
-    //esdhc_base_pointer->interrupt_status_enable |= 0x007f0123;
+       /* Enable Interrupt */
+       esdhc_base_pointer->interrupt_status_enable |= ESDHC_INTERRUPT_ENABLE;
+       //esdhc_base_pointer->interrupt_status_enable |= 0x007f0123;
 
 #if 0
-    if (esdhc_check_for_send_cmd(cmd->data_present)) {
-        diag_printf("Data/Cmd Line Busy.\n");
-        return FAIL;
-    }
+       if (esdhc_check_for_send_cmd(cmd->data_present)) {
+               diag_printf("Data/Cmd Line Busy.\n");
+               return FAIL;
+       }
 #endif
 
-    /* Configure Command    */
-    esdhc_cmd_config(cmd);
-
-    /* Wait interrupt (END COMMAND RESPONSE)  */
-    //diag_printf("Wait for CMD Response.\n");
-    if (esdhc_wait_end_cmd_resp_intr()) {
-        diag_printf("Wait CMD (%d) RESPONSE TIMEOUT.\n", cmd->command);
-        return FAIL;
-    }
-    //Just test for Erase functionality:Lewis-20080505:
-    if (cmd->command == CMD38) {
-        flash_dprintf(FLASH_DEBUG_MAX, "%s:Check DAT0 status:\n",
-                  __FUNCTION__);
-        //while(((esdhc_base_pointer->present_state) & 0x01000004)){
-        //   flash_dprintf(FLASH_DEBUG_MAX,".");
-        //   hal_delay_us(1000);
-        //}
-        /* I'm not sure the minimum value of delay */
-        hal_delay_us(100000);
-        hal_delay_us(100000);
-        hal_delay_us(100000);
-        flash_dprintf(FLASH_DEBUG_MAX,
-                  "\nCheck DAT0 status DONE: present_state=%x\n",
-                  (cyg_uint32) (esdhc_base_pointer->present_state));
-    }
-
-    /* Mask all interrupts     */
-    //esdhc_base_pointer->interrupt_signal_enable =0;
-
-    /* Check if an error occured    */
-    return esdhc_check_response();
+       /* Configure Command    */
+       esdhc_cmd_config(cmd);
+
+       /* Wait interrupt (END COMMAND RESPONSE)  */
+       //diag_printf("Wait for CMD Response.\n");
+       if (esdhc_wait_end_cmd_resp_intr()) {
+               diag_printf("Wait CMD (%d) RESPONSE TIMEOUT.\n", cmd->command);
+               return FAIL;
+       }
+       //Just test for Erase functionality:Lewis-20080505:
+       if (cmd->command == CMD38) {
+               flash_dprintf(FLASH_DEBUG_MAX, "%s:Check DAT0 status:\n",
+                                       __FUNCTION__);
+               //while(((esdhc_base_pointer->present_state) & 0x01000004)){
+               //   flash_dprintf(FLASH_DEBUG_MAX,".");
+               //   hal_delay_us(1000);
+               //}
+               /* I'm not sure the minimum value of delay */
+               hal_delay_us(100000);
+               hal_delay_us(100000);
+               hal_delay_us(100000);
+               flash_dprintf(FLASH_DEBUG_MAX,
+                                       "\nCheck DAT0 status DONE: present_state=%x\n",
+                                       (cyg_uint32) (esdhc_base_pointer->present_state));
+       }
+
+       /* Mask all interrupts     */
+       //esdhc_base_pointer->interrupt_signal_enable =0;
+
+       /* Check if an error occured    */
+       return esdhc_check_response();
 }
 
 static void esdhc_cmd_config(command_t * cmd)
 {
-    unsigned int transfer_type;
-
-    /* Write Command Argument in Command Argument Register */
-    esdhc_base_pointer->command_argument = cmd->arg;
-
-    /*    *Configure e-SDHC Register value according to Command    */
-    transfer_type = (((cmd->data_transfer) << DATA_TRANSFER_SHIFT) |
-             ((cmd->response_format) << RESPONSE_FORMAT_SHIFT) |
-             ((cmd->data_present) << DATA_PRESENT_SHIFT) |
-             ((cmd->crc_check) << CRC_CHECK_SHIFT) |
-             ((cmd->cmdindex_check) << CMD_INDEX_CHECK_SHIFT) |
-             ((cmd->command) << CMD_INDEX_SHIFT) |
-             ((cmd->
-               block_count_enable_check) <<
-              BLOCK_COUNT_ENABLE_SHIFT) | ((cmd->
-                            multi_single_block) <<
-                               MULTI_SINGLE_BLOCK_SELECT_SHIFT));
-
-    esdhc_base_pointer->command_transfer_type = transfer_type;
-
-    //diag_printf("arg: 0x%x | tp: 0x%x\n", esdhc_base_pointer->command_argument, esdhc_base_pointer->command_transfer_type);
-
+       unsigned int transfer_type;
+
+       /* Write Command Argument in Command Argument Register */
+       esdhc_base_pointer->command_argument = cmd->arg;
+
+       /*    *Configure e-SDHC Register value according to Command    */
+       transfer_type = (((cmd->data_transfer) << DATA_TRANSFER_SHIFT) |
+                                       ((cmd->response_format) << RESPONSE_FORMAT_SHIFT) |
+                                       ((cmd->data_present) << DATA_PRESENT_SHIFT) |
+                                       ((cmd->crc_check) << CRC_CHECK_SHIFT) |
+                                       ((cmd->cmdindex_check) << CMD_INDEX_CHECK_SHIFT) |
+                                       ((cmd->command) << CMD_INDEX_SHIFT) |
+                                       ((cmd->
+                                               block_count_enable_check) <<
+                                               BLOCK_COUNT_ENABLE_SHIFT) | ((cmd->
+                                                                                                                                                               multi_single_block) <<
+                                                                                                       MULTI_SINGLE_BLOCK_SELECT_SHIFT));
+
+       esdhc_base_pointer->command_transfer_type = transfer_type;
+
+       //diag_printf("arg: 0x%x | tp: 0x%x\n", esdhc_base_pointer->command_argument, esdhc_base_pointer->command_transfer_type);
 }
 
 static int esdhc_wait_end_cmd_resp_intr(void)
 {
-    /* Wait interrupt (END COMMAND RESPONSE)  */
-    cyg_uint32 i = 50000;
-    while (!
-           ((esdhc_base_pointer->
-         interrupt_status) & ESDHC_STATUS_END_CMD_RESP_TIME_MSK) && i) {
-        i--;
-        hal_delay_us(10);
-        //diag_printf("0x%x\n", esdhc_base_pointer->interrupt_status);
-    }
-
-    if (!
-        ((esdhc_base_pointer->
-          interrupt_status) & ESDHC_STATUS_END_CMD_RESP_TIME_MSK)) {
-        //diag_printf("%s: can't get END COMMAND RESPONSE! Tried %d times\n", __FUNCTION__, (5000000-i));
-        return FAIL;
-    }
-
-    return SUCCESS;
+       /* Wait interrupt (END COMMAND RESPONSE)  */
+       cyg_uint32 i = 50000;
+       while (!
+               ((esdhc_base_pointer->
+                       interrupt_status) & ESDHC_STATUS_END_CMD_RESP_TIME_MSK) && i) {
+               i--;
+               hal_delay_us(10);
+               //diag_printf("0x%x\n", esdhc_base_pointer->interrupt_status);
+       }
+
+       if (!
+               ((esdhc_base_pointer->
+                       interrupt_status) & ESDHC_STATUS_END_CMD_RESP_TIME_MSK)) {
+               //diag_printf("%s: can't get END COMMAND RESPONSE! Tried %d times\n", __FUNCTION__, (5000000-i));
+               return FAIL;
+       }
+
+       return SUCCESS;
 }
 
 static cyg_uint32 esdhc_check_response(void)
 {
-    cyg_uint32 status = FAIL;
-
-    /* Check whether the interrupt is an END_CMD_RESP
-     * or a response time out or a CRC error
-     */
-    if ((esdhc_base_pointer->
-         interrupt_status & ESDHC_STATUS_END_CMD_RESP_MSK)
-        && !(esdhc_base_pointer->
-         interrupt_status & ESDHC_STATUS_TIME_OUT_RESP_MSK)
-        && !(esdhc_base_pointer->
-         interrupt_status & ESDHC_STATUS_RESP_CRC_ERR_MSK)
-        && !(esdhc_base_pointer->
-         interrupt_status & ESDHC_STATUS_RESP_INDEX_ERR_MSK)) {
-
-        status = SUCCESS;
-    } else {
-        //diag_printf("Warning: Check CMD response, Intr Status: 0x%x\n", esdhc_base_pointer->interrupt_status);
-        status = FAIL;
-    }
-
-    return status;
-
+       cyg_uint32 status = FAIL;
+
+       /* Check whether the interrupt is an END_CMD_RESP
+        * or a response time out or a CRC error
+        */
+       if ((esdhc_base_pointer->
+                       interrupt_status & ESDHC_STATUS_END_CMD_RESP_MSK)
+               && !(esdhc_base_pointer->
+                       interrupt_status & ESDHC_STATUS_TIME_OUT_RESP_MSK)
+               && !(esdhc_base_pointer->
+                       interrupt_status & ESDHC_STATUS_RESP_CRC_ERR_MSK)
+               && !(esdhc_base_pointer->
+                       interrupt_status & ESDHC_STATUS_RESP_INDEX_ERR_MSK)) {
+
+               status = SUCCESS;
+       } else {
+               //diag_printf("Warning: Check CMD response, Intr Status: 0x%x\n", esdhc_base_pointer->interrupt_status);
+               status = FAIL;
+       }
+
+       return status;
 }
 
 void host_read_response(command_response_t * cmd_resp)
 {
-    /* get response values from e-SDHC CMDRSP registers. */
-    cmd_resp->cmd_rsp0 = (cyg_uint32) esdhc_base_pointer->command_response0;
-    cmd_resp->cmd_rsp1 = (cyg_uint32) esdhc_base_pointer->command_response1;
-    cmd_resp->cmd_rsp2 = (cyg_uint32) esdhc_base_pointer->command_response2;
-    cmd_resp->cmd_rsp3 = (cyg_uint32) esdhc_base_pointer->command_response3;
+       /* get response values from e-SDHC CMDRSP registers. */
+       cmd_resp->cmd_rsp0 = (cyg_uint32) esdhc_base_pointer->command_response0;
+       cmd_resp->cmd_rsp1 = (cyg_uint32) esdhc_base_pointer->command_response1;
+       cmd_resp->cmd_rsp2 = (cyg_uint32) esdhc_base_pointer->command_response2;
+       cmd_resp->cmd_rsp3 = (cyg_uint32) esdhc_base_pointer->command_response3;
 }
 
-static void esdhc_wait_buf_rdy_intr(cyg_uint32 mask,
-                    multi_single_block_select
-                    multi_single_block)
+static void __attribute__((unused)) esdhc_wait_buf_rdy_intr(cyg_uint32 mask,
+                                                                       multi_single_block_select
+                                                                       multi_single_block)
 {
 
-    /* Wait interrupt (BUF_READ_RDY)    */
+       /* Wait interrupt (BUF_READ_RDY)    */
 
-    cyg_uint32 i;
-    for (i = 3000; i > 0; i--) {
-        if (esdhc_base_pointer->interrupt_status & mask) {
-            break;
-        }
-        hal_delay_us(100);
-    }
+       cyg_uint32 i;
+       for (i = 3000; i > 0; i--) {
+               if (esdhc_base_pointer->interrupt_status & mask) {
+                       break;
+               }
+               hal_delay_us(100);
+       }
 
-    if (multi_single_block == MULTIPLE
-        && esdhc_base_pointer->interrupt_status & mask)
-        esdhc_base_pointer->interrupt_status |= mask;
-    if (i == 0)
-        flash_dprintf(FLASH_DEBUG_MAX, "%s:Debug: tried %d times\n",
-                  __FUNCTION__, (3000 - i));
+       if (multi_single_block == MULTIPLE
+               && esdhc_base_pointer->interrupt_status & mask)
+               esdhc_base_pointer->interrupt_status |= mask;
+       if (i == 0)
+               flash_dprintf(FLASH_DEBUG_MAX, "%s:Debug: tried %d times\n",
+                                       __FUNCTION__, (3000 - i));
 
 }
 
 static void esdhc_wait_op_done_intr(cyg_uint32 transfer_mask)
 {
-    /* Wait interrupt (Transfer Complete)    */
-
-    cyg_uint32 i;
-    while (!(esdhc_base_pointer->interrupt_status & transfer_mask)) ;
+       /* Wait interrupt (Transfer Complete)    */
 
-    //diag_printf("Wait OP Done Failed.\n");
-    //flash_dprintf(FLASH_DEBUG_MAX,"%s:Debug: tried %d times\n", __FUNCTION__, (3001-i));
+       while (!(esdhc_base_pointer->interrupt_status & transfer_mask)) ;
 
+       //diag_printf("Wait OP Done Failed.\n");
+       //flash_dprintf(FLASH_DEBUG_MAX,"%s:Debug: tried %d times\n", __FUNCTION__, (3001-i));
 }
 
 static cyg_uint32 esdhc_check_data(cyg_uint32 op_done_mask,
@@ -456,7 +449,7 @@ cyg_uint32 host_data_write(cyg_uint32 * src_ptr, cyg_uint32 write_len)
 
 }
 
-static int esdhc_check_for_send_cmd(int data_present)
+static int __attribute__((unused)) esdhc_check_for_send_cmd(int data_present)
 {
 
     int status = SUCCESS;
index 11c33a9ee3e54301b2435c9ed8767e50d91290e2..cf80b2a699b6c47644f43c044679518a5bd1872b 100644 (file)
@@ -66,245 +66,245 @@ cyg_uint32 address_mode;    /* Global variable for addressing mode */
 
 cyg_uint32 mmc_init(cyg_uint32 bus_width)
 {
-    cyg_uint32 status = FAIL;
-    cyg_uint32 spec_version;
-    /* Get CID number of MMC Card */
-    if (!mxcmci_get_cid()) {
-        /* Set RCA of the MMC Card */
-        if (!mmc_set_rca()) {
-            flash_dprintf(FLASH_DEBUG_MAX, "%s:  mmc_set_rca OK!",
-                      __FUNCTION__);
-            /* Get Spec version supported by the card */
-            spec_version = mmc_get_spec_ver();
-            //diag_printf("SPEC Version:  %d\n", spec_version);
-
-            /*Enable operating frequency */
-            host_cfg_clock(OPERATING_FREQ);
-
-            /*Put MMC in Transfer State */
-            if (!mxcmci_trans_prepare()) {
+       cyg_uint32 status = FAIL;
+       cyg_uint32 spec_version;
+       /* Get CID number of MMC Card */
+       if (!mxcmci_get_cid()) {
+               /* Set RCA of the MMC Card */
+               if (!mmc_set_rca()) {
+                       flash_dprintf(FLASH_DEBUG_MAX, "%s:  mmc_set_rca OK!",
+                                               __FUNCTION__);
+                       /* Get Spec version supported by the card */
+                       spec_version = mmc_get_spec_ver();
+                       //diag_printf("SPEC Version:  %d\n", spec_version);
+
+                       /*Enable operating frequency */
+                       host_cfg_clock(OPERATING_FREQ);
+
+                       /*Put MMC in Transfer State */
+                       if (!mxcmci_trans_prepare()) {
 #if 0
-                if (mmc_set_high_speed_mode()) {
-                    return FAIL;
-                }
+                               if (mmc_set_high_speed_mode()) {
+                                       return FAIL;
+                               }
 #endif
 
-                /* Set block length for transfer */
-                //diag_printf("Send CMD to Set Block Length.\n");
-                if (sdmmc_set_blklen(BLK_LEN))
-                    return FAIL;
+                               /* Set block length for transfer */
+                               //diag_printf("Send CMD to Set Block Length.\n");
+                               if (sdmmc_set_blklen(BLK_LEN))
+                                       return FAIL;
 
-                flash_dprintf(FLASH_DEBUG_MAX, "%s:  mxcmci_trans_prepare OK!",
-                          __FUNCTION__);
+                               flash_dprintf(FLASH_DEBUG_MAX, "%s:  mxcmci_trans_prepare OK!",
+                                                       __FUNCTION__);
 
-                if (!mmc_set_bus_width(bus_width)) {
-                    esdhc_base_pointer->protocol_control &= ~(0x3 << 1);
-                    esdhc_base_pointer->protocol_control |= (bus_width >> 2) << 1;
-                    status = SUCCESS;
-                    diag_printf("Bus Width:    %d\n",
-                            bus_width);
-                }
+                               if (!mmc_set_bus_width(bus_width)) {
+                                       esdhc_base_pointer->protocol_control &= ~(0x3 << 1);
+                                       esdhc_base_pointer->protocol_control |= (bus_width >> 2) << 1;
+                                       status = SUCCESS;
+                                       diag_printf("Bus Width:    %d\n",
+                                                               bus_width);
+                               }
 
-            }
-        }
-    }
+                       }
+               }
+       }
 
-    return status;
+       return status;
 
 }
 
 cyg_uint32 mmc_data_read(cyg_uint32 * dest_ptr, cyg_uint32 length,
              cyg_uint32 offset)
 {
-    command_t cmd;
-    int len;
-    cyg_uint32 read_block_status = 0;
-    cyg_uint32 blk_len = BLK_LEN;
-    unsigned int SectorNum = 0;
-
-    /* Assing length of data to be read */
-    SectorNum = length / blk_len;
-    if ((length % blk_len) != 0)
-        SectorNum++;
-    /* hight capacity card uses sector mode */
-    if(HighCapacityCard)
-       offset = offset/512;
-
-    /* wait until in transfer mode */
-    while (mxcmci_trans_status()) {
-        hal_delay_us(5);
-    }
-
-      reread:
-    /* Configure interface block and number of blocks */
-    host_cfg_block(BLK_LEN, SectorNum);
-
-    if (SectorNum == 1) {
-        //diag_printf("Send CMD17...\n");
-        /* Comfigure command CMD17 for single block read */
-        mxcmci_cmd_config(&cmd, CMD17, offset, READ, RESPONSE_48,
-                  DATA_PRESENT, ENABLE, ENABLE);
-
-        if (host_send_cmd(&cmd) == FAIL) {
-            diag_printf("%s: Can't send CMD17!\n", __FUNCTION__);
-            esdhc_softreset(ESDHC_RESET_CMD_MSK |
-                    ESDHC_RESET_DAT_MSK);
-            read_block_status = FAIL;
-
-        } else {
-            //diag_printf("host_data_read! dest_ptr: 0%x \n", dest_ptr);
-            /* Call interface Data read function */
-            read_block_status = host_data_read(dest_ptr, BLK_LEN);
-
-            if (read_block_status) {    /* fail */
-                //diag_printf("%s: Failed, read_block_status =%d\n", __FUNCTION__, read_block_status);
-                /* re-transfer if data transfer error occurs */
-                goto reread;
-            }
-        }
-    } else {        /* read multi-blocks */
-
-        /* Comfigure command CMD18 for multiple block read */
-        mxcmci_cmd_config(&cmd, CMD18, offset, READ, RESPONSE_48,
-                  DATA_PRESENT, ENABLE, ENABLE);
-
-        if (host_send_cmd(&cmd) == FAIL) {
-            diag_printf("%s: Can't send CMD18!\n", __FUNCTION__);
-            esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
-            read_block_status = FAIL;
-        } else {
-            /* Call interface Data read function */
-            read_block_status =
-                host_data_read(dest_ptr, BLK_LEN * SectorNum);
-
-            /* Comfigure command CMD12 for multi-block read stop */
-            mxcmci_cmd_config(&cmd, CMD12, 0, READ, RESPONSE_48,
-                      DATA_PRESENT_NONE, ENABLE, ENABLE);
-
-            if (host_send_cmd(&cmd) == FAIL) {
-                diag_printf("%s: Can't send CMD12!\n",
-                        __FUNCTION__);
-                esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
-                //read_block_status = FAIL;
-            }
-
-            if (read_block_status) {    /* fail */
-                //diag_printf("%s: Failed, read_block_status =%d\n", __FUNCTION__, read_block_status);
-                /* re-transfer if data transfer error occurs */
-                goto reread;
-            }
-
-        }
-
-    }
-    return read_block_status;
+       command_t cmd;
+       int len;
+       cyg_uint32 read_block_status = 0;
+       cyg_uint32 blk_len = BLK_LEN;
+       unsigned int SectorNum = 0;
+
+       /* Assing length of data to be read */
+       SectorNum = length / blk_len;
+       if ((length % blk_len) != 0)
+               SectorNum++;
+       /* hight capacity card uses sector mode */
+       if(HighCapacityCard)
+               offset = offset/512;
+
+       /* wait until in transfer mode */
+       while (mxcmci_trans_status()) {
+               hal_delay_us(5);
+       }
+
+reread:
+       /* Configure interface block and number of blocks */
+       host_cfg_block(BLK_LEN, SectorNum);
+
+       if (SectorNum == 1) {
+               //diag_printf("Send CMD17...\n");
+               /* Comfigure command CMD17 for single block read */
+               mxcmci_cmd_config(&cmd, CMD17, offset, READ, RESPONSE_48,
+                                               DATA_PRESENT, ENABLE, ENABLE);
+
+               if (host_send_cmd(&cmd) == FAIL) {
+                       diag_printf("%s: Can't send CMD17!\n", __FUNCTION__);
+                       esdhc_softreset(ESDHC_RESET_CMD_MSK |
+                                                       ESDHC_RESET_DAT_MSK);
+                       read_block_status = FAIL;
+
+               } else {
+                       //diag_printf("host_data_read! dest_ptr: 0%x \n", dest_ptr);
+                       /* Call interface Data read function */
+                       read_block_status = host_data_read(dest_ptr, BLK_LEN);
+
+                       if (read_block_status) {    /* fail */
+                               //diag_printf("%s: Failed, read_block_status =%d\n", __FUNCTION__, read_block_status);
+                               /* re-transfer if data transfer error occurs */
+                               goto reread;
+                       }
+               }
+       } else {        /* read multi-blocks */
+
+               /* Comfigure command CMD18 for multiple block read */
+               mxcmci_cmd_config(&cmd, CMD18, offset, READ, RESPONSE_48,
+                                               DATA_PRESENT, ENABLE, ENABLE);
+
+               if (host_send_cmd(&cmd) == FAIL) {
+                       diag_printf("%s: Can't send CMD18!\n", __FUNCTION__);
+                       esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
+                       read_block_status = FAIL;
+               } else {
+                       /* Call interface Data read function */
+                       read_block_status =
+                               host_data_read(dest_ptr, BLK_LEN * SectorNum);
+
+                       /* Comfigure command CMD12 for multi-block read stop */
+                       mxcmci_cmd_config(&cmd, CMD12, 0, READ, RESPONSE_48,
+                                                       DATA_PRESENT_NONE, ENABLE, ENABLE);
+
+                       if (host_send_cmd(&cmd) == FAIL) {
+                               diag_printf("%s: Can't send CMD12!\n",
+                                                       __FUNCTION__);
+                               esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
+                               //read_block_status = FAIL;
+                       }
+
+                       if (read_block_status) {    /* fail */
+                               //diag_printf("%s: Failed, read_block_status =%d\n", __FUNCTION__, read_block_status);
+                               /* re-transfer if data transfer error occurs */
+                               goto reread;
+                       }
+
+               }
+
+       }
+       return read_block_status;
 }
 
 cyg_uint32 mmc_data_write(cyg_uint32 * src_ptr, cyg_uint32 length,
               cyg_uint32 offset)
 {
 
-    command_t cmd;
-    cyg_int32 len;
-    cyg_uint32 blk_len = BLK_LEN;
-    cyg_uint32 write_block_status = SUCCESS;
-    unsigned int SectorNum;
-    //int counter;
-    //diag_printf("%s: src: 0x%x, offset: 0x%x, length: 0x%x\n", __FUNCTION__, (unsigned int)src_ptr, offset, length);
-    /* Write data size aligned with block size */
-    SectorNum = length / blk_len;
-    if ((length % blk_len) != 0)
-        SectorNum++;
-
-    /* hight capacity card uses sector mode */
-    if(HighCapacityCard)
-        offset = offset/512;
-
-    //need waiting until CARD out of Prg status, or will cause CMD25 timeout
-    //hal_delay_us(100);
-
-    //StartCounter();
-
-    while (mxcmci_trans_status()) {
-        hal_delay_us(2);
-    }
-
-    //counter = StopCounter();
-    //diag_printf("counter: 0x%x\n",counter);
-
-      rewrite:
-    /* Configure interface block and number of blocks , SctorNum will decrease to zero after transfer */
-    host_cfg_block(BLK_LEN, SectorNum);
-
-    if (SectorNum == 1) {
-        //diag_printf("Send CMD24...\n");
-        /* Comfigure command CMD24 for single block write */
-        mxcmci_cmd_config(&cmd, CMD24, offset, WRITE, RESPONSE_48,
-                  DATA_PRESENT, ENABLE, ENABLE);
-
-        if (host_send_cmd(&cmd) == FAIL) {
-            diag_printf("%s: Failed in configuring CMD24\n",
-                    __FUNCTION__);
-            esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
-            write_block_status = FAIL;
-
-            //hal_delay_us(1000);
-            goto rewrite;
-
-        } else {
-            //diag_printf("Start host_data_write:\n");
-            /* Call interface write read function */
-            write_block_status = host_data_write(src_ptr, BLK_LEN);
-            //diag_printf("0x%x\n", esdhc_base_pointer->present_state);
-
-            if (write_block_status) {    /* fail */
-                //diag_printf("transfer failed.(0x%x)\n", esdhc_base_pointer->block_attributes);
-                while (mxcmci_trans_status()) ;
-                //diag_printf("%s: Failed, write_block_status=%d\n", __FUNCTION__, write_block_status);
-                /* re-transfer */
-                goto rewrite;
-            }
-
-        }
-    } else {        /* multi-block write */
-
-        //diag_printf("Send CMD25...\n");
-        /* Comfigure command CMD25 for single block write */
-        mxcmci_cmd_config(&cmd, CMD25, offset, WRITE, RESPONSE_48,
-                  DATA_PRESENT, ENABLE, ENABLE);
-
-        if (host_send_cmd(&cmd) == FAIL) {
-            //diag_printf("%s: Failed in configuring CMD25\n",
-            //        __FUNCTION__);
-            esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
-            write_block_status = FAIL;
-            goto rewrite;
-        } else {
-            /* Call interface write read function */
-            write_block_status =
-                host_data_write(src_ptr, SectorNum * BLK_LEN);
-
-            /* Comfigure command CMD12 for multi-block read stop */
-            mxcmci_cmd_config(&cmd, CMD12, 0, READ, RESPONSE_48,
-                      DATA_PRESENT_NONE, ENABLE, ENABLE);
-
-            if (host_send_cmd(&cmd) == FAIL) {
-                diag_printf("%s: Can't send CMD12!\n",
-                        __FUNCTION__);
-                esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
-                //write_block_status = FAIL;
-            }
-
-            if (write_block_status) {    /* fail */
-                //diag_printf("%s: Failed, write_block_status=%d\n", __FUNCTION__, write_block_status);
-                while (mxcmci_trans_status());
-                /* re-transfer */
-                goto rewrite;
-            }
-        }
-    }
-
-    return write_block_status;
+       command_t cmd;
+       cyg_int32 len;
+       cyg_uint32 blk_len = BLK_LEN;
+       cyg_uint32 write_block_status = SUCCESS;
+       unsigned int SectorNum;
+       //int counter;
+       //diag_printf("%s: src: 0x%x, offset: 0x%x, length: 0x%x\n", __FUNCTION__, (unsigned int)src_ptr, offset, length);
+       /* Write data size aligned with block size */
+       SectorNum = length / blk_len;
+       if ((length % blk_len) != 0)
+               SectorNum++;
+
+       /* hight capacity card uses sector mode */
+       if(HighCapacityCard)
+               offset = offset/512;
+
+       //need waiting until CARD out of Prg status, or will cause CMD25 timeout
+       //hal_delay_us(100);
+
+       //StartCounter();
+
+       while (mxcmci_trans_status()) {
+               hal_delay_us(2);
+       }
+
+       //counter = StopCounter();
+       //diag_printf("counter: 0x%x\n",counter);
+
+rewrite:
+       /* Configure interface block and number of blocks , SctorNum will decrease to zero after transfer */
+       host_cfg_block(BLK_LEN, SectorNum);
+
+       if (SectorNum == 1) {
+               //diag_printf("Send CMD24...\n");
+               /* Comfigure command CMD24 for single block write */
+               mxcmci_cmd_config(&cmd, CMD24, offset, WRITE, RESPONSE_48,
+                                               DATA_PRESENT, ENABLE, ENABLE);
+
+               if (host_send_cmd(&cmd) == FAIL) {
+                       diag_printf("%s: Failed in configuring CMD24\n",
+                                               __FUNCTION__);
+                       esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
+                       write_block_status = FAIL;
+
+                       //hal_delay_us(1000);
+                       goto rewrite;
+
+               } else {
+                       //diag_printf("Start host_data_write:\n");
+                       /* Call interface write read function */
+                       write_block_status = host_data_write(src_ptr, BLK_LEN);
+                       //diag_printf("0x%x\n", esdhc_base_pointer->present_state);
+
+                       if (write_block_status) {    /* fail */
+                               //diag_printf("transfer failed.(0x%x)\n", esdhc_base_pointer->block_attributes);
+                               while (mxcmci_trans_status()) ;
+                               //diag_printf("%s: Failed, write_block_status=%d\n", __FUNCTION__, write_block_status);
+                               /* re-transfer */
+                               goto rewrite;
+                       }
+
+               }
+       } else {        /* multi-block write */
+
+               //diag_printf("Send CMD25...\n");
+               /* Comfigure command CMD25 for single block write */
+               mxcmci_cmd_config(&cmd, CMD25, offset, WRITE, RESPONSE_48,
+                                               DATA_PRESENT, ENABLE, ENABLE);
+
+               if (host_send_cmd(&cmd) == FAIL) {
+                       //diag_printf("%s: Failed in configuring CMD25\n",
+                       //        __FUNCTION__);
+                       esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
+                       write_block_status = FAIL;
+                       goto rewrite;
+               } else {
+                       /* Call interface write read function */
+                       write_block_status =
+                               host_data_write(src_ptr, SectorNum * BLK_LEN);
+
+                       /* Comfigure command CMD12 for multi-block read stop */
+                       mxcmci_cmd_config(&cmd, CMD12, 0, READ, RESPONSE_48,
+                                                       DATA_PRESENT_NONE, ENABLE, ENABLE);
+
+                       if (host_send_cmd(&cmd) == FAIL) {
+                               diag_printf("%s: Can't send CMD12!\n",
+                                                       __FUNCTION__);
+                               esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
+                               //write_block_status = FAIL;
+                       }
+
+                       if (write_block_status) {    /* fail */
+                               //diag_printf("%s: Failed, write_block_status=%d\n", __FUNCTION__, write_block_status);
+                               while (mxcmci_trans_status());
+                               /* re-transfer */
+                               goto rewrite;
+                       }
+               }
+       }
+
+       return write_block_status;
 
 }