From: lothar Date: Thu, 14 Jan 2010 16:22:53 +0000 (+0000) Subject: TX51 pre-release X-Git-Tag: v1.5.3~35 X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-redboot.git;a=commitdiff_plain;h=981551567b3d95830ff3ea683f07e93d1cbdafe7 TX51 pre-release --- diff --git a/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc.h b/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc.h index fa7fbc59..4e9b7642 100644 --- a/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc.h +++ b/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc.h @@ -122,31 +122,33 @@ #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_ diff --git a/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v2.h b/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v2.h index da2b4242..f0de7ee1 100644 --- a/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v2.h +++ b/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v2.h @@ -55,7 +55,7 @@ #include #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() diff --git a/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v3.h b/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v3.h index a604287b..d17782dc 100644 --- a/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v3.h +++ b/packages/devs/flash/arm/mxc/v2_0/include/mxc_nfc_v3.h @@ -55,76 +55,123 @@ #include #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 #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_ diff --git a/packages/devs/flash/arm/mxc/v2_0/include/mxcmci_host.h b/packages/devs/flash/arm/mxc/v2_0/include/mxcmci_host.h index 20060484..8e1d979b 100644 --- a/packages/devs/flash/arm/mxc/v2_0/include/mxcmci_host.h +++ b/packages/devs/flash/arm/mxc/v2_0/include/mxcmci_host.h @@ -57,7 +57,7 @@ #include -#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 */ @@ -66,13 +66,13 @@ #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 @@ -108,7 +108,7 @@ #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 @@ -127,57 +127,57 @@ 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 index 00000000..e913db6d --- /dev/null +++ b/packages/devs/flash/arm/mxc/v2_0/include/tx51_nand_bbt.h @@ -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; diff --git a/packages/devs/flash/arm/mxc/v2_0/src/mxc_mmc.c b/packages/devs/flash/arm/mxc/v2_0/src/mxc_mmc.c index 9ecd22ee..118f6f92 100644 --- a/packages/devs/flash/arm/mxc/v2_0/src/mxc_mmc.c +++ b/packages/devs/flash/arm/mxc/v2_0/src/mxc_mmc.c @@ -55,6 +55,7 @@ //========================================================================== #include +#include #include #include #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 diff --git a/packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c b/packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c index 82309b94..fbeffcc1 100644 --- a/packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c +++ b/packages/devs/flash/arm/mxc/v2_0/src/mxc_nfc.c @@ -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) { diff --git a/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_core.c b/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_core.c index 56b7e41f..43d1fb62 100644 --- a/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_core.c +++ b/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_core.c @@ -51,14 +51,15 @@ // //========================================================================== +#include #include #include #include #include #include -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); diff --git a/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_host.c b/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_host.c index 04b5ea1d..07e5133e 100644 --- a/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_host.c +++ b/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_host.c @@ -51,6 +51,7 @@ // //========================================================================== +#include #include #include #include @@ -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; diff --git a/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_mmc.c b/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_mmc.c index 11c33a9e..cf80b2a6 100644 --- a/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_mmc.c +++ b/packages/devs/flash/arm/mxc/v2_0/src/mxcmci_mmc.c @@ -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; }