#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
/*!
* @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;
}
/*!
* @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();
}
/*!
*/
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.
}
/*!
*/
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)
#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_
#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.
};
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()
#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);
}
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
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);
}
/*!
* @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.
*/
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);
}
/*!
*/
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_
#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
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;
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;
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_ */
--- /dev/null
+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;
//==========================================================================
#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
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;
}
void mmcflash_query(void* data)
#endif
{
- return card_flash_query(data);
+ card_flash_query(data);
}
#ifndef MXCFLASH_SELECT_MULTI
int mmcflash_hwr_map_error(int e)
#endif
{
- return e;
+ return e;
}
#ifndef MXCFLASH_SELECT_MULTI
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
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
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;
#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
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;
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) {
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)
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)) &&
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) {
return FLASH_ERR_DRV_WRONG_PART;
}
- nand_flash_index = i;
mxcnfc_init_ok = true;
if (NF_PG_SZ == 2048) {
__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);
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++;
{
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);
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) {
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;
}
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;
}
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.
}
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);
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);
}
// 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
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);
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)
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;
// 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
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);
}
// 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
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);
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;
}
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);
} else {
nfc_erase_region(ra, len, 1, 1);
}
+ FLASH_Disable((u8 *)ra, (u8 *)ra + len);
diag_printf("\n");
}
{
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);
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) {
//
//==========================================================================
+#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
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;
}
/*==========================================================================
}
-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;
}
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);
//
//==========================================================================
+#include <cyg/infra/diag.h>
#include <cyg/io/mxcmci_host.h>
#include <cyg/io/mxcmci_core.h>
#include <cyg/io/mxcmci_mmc.h>
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)
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,
}
-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;
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;
}