#include <pkgconf/devs_flash_onmxc.h>
#include "mxc_nand_specifics.h"
-#define NFC_DEBUG_MIN 1
-#define NFC_DEBUG_MED 2
-#define NFC_DEBUG_MAX 3
-#define NFC_DEBUG_DEF NFC_DEBUG_MED
-
#define PG_2K_DATA_OP_MULTI_CYCLES() false
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef unsigned char u8;
-
-#define ADDR_INPUT_SIZE 8
//----------------------------------------------------------------------------
// Common device details.
-#define FLASH_Read_ID (0x90)
-#if CYGHWR_DEVS_FLASH_MXC_NAND_RESET_WORKAROUND
-#define FLASH_Reset 0xFFFF
+#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)
+#if defined (NFC_V2_0)
+#define NAND_SPAR_BUF0 (NFC_BASE + 0x800)
+#define NAND_SPAR_BUF1 (NFC_BASE + 0x810)
+#define NAND_SPAR_BUF2 (NFC_BASE + 0x820)
+#define NAND_SPAR_BUF3 (NFC_BASE + 0x830)
+#define NAND_RESERVED (NFC_BASE + 0x840)
+#define NFC_BUF_COUNT 4
+#define NFC_SPARE_BUF_SZ 16
+#elif defined (NFC_V2_1)
+#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 NFC_BUF_COUNT 8
+#define NFC_SPARE_BUF_SZ 64
#else
-#define FLASH_Reset (0xFF)
+#error NOT supported
#endif
-#define FLASH_Read_Mode1 (0x00)
-#define FLASH_Read_Mode1_2K (0x30)
-#define FLASH_Read_Mode2 (0x01)
-#define FLASH_Read_Mode3 (0x50)
-#define FLASH_Program (0x10)
-#define FLASH_Send_Data (0x80)
-#define FLASH_Status (0x70)
-#define FLASH_Block_Erase (0x60)
-#define FLASH_Start_Erase (0xD0)
-
-#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_SPAR_BUF0 (NFC_BASE + 0x800)
-#define NAND_SPAR_BUF1 (NFC_BASE + 0x810)
-#define NAND_SPAR_BUF2 (NFC_BASE + 0x820)
-#define NAND_SPAR_BUF3 (NFC_BASE + 0x830)
-#define NAND_RESERVED (NFC_BASE + 0x840)
-
-#define NFC_BUFSIZE_REG (NAND_REG_BASE + 0x00)
-#define RAM_BUFFER_ADDRESS_REG (NAND_REG_BASE + 0x04)
-#define NAND_FLASH_ADD_REG (NAND_REG_BASE + 0x06)
-#define NAND_FLASH_CMD_REG (NAND_REG_BASE + 0x08)
-#define NFC_CONFIGURATION_REG (NAND_REG_BASE + 0x0A)
-#define ECC_STATUS_RESULT_REG (NAND_REG_BASE + 0x0C)
-#define ECC_RSLT_MAIN_AREA_REG (NAND_REG_BASE + 0x0E)
-#define ECC_RSLT_SPARE_AREA_REG (NAND_REG_BASE + 0x10)
-#define NF_WR_PROT_REG (NAND_REG_BASE + 0x12)
-#define UNLOCK_START_BLK_ADD_REG (NAND_REG_BASE + 0x14)
-#define UNLOCK_END_BLK_ADD_REG (NAND_REG_BASE + 0x16)
-#define NAND_FLASH_WR_PR_ST_REG (NAND_REG_BASE + 0x18)
-#define NAND_FLASH_CONFIG1_REG (NAND_REG_BASE + 0x1A)
-#define NAND_FLASH_CONFIG2_REG (NAND_REG_BASE + 0x1C)
-enum nfc_internal_buf {
- RAM_BUF_0 = 0x0 << 4,
- RAM_BUF_1 = 0x1 << 4,
- RAM_BUF_2 = 0x2 << 4,
- RAM_BUF_3 = 0x3 << 4,
-};
+#define ECC_STATUS_RESULT_REG (NAND_REG_BASE + 0x08)
+#define NUM_OF_CS_LINES 1
+#define NFC_BUFSIZE 0
-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,
-};
+#define NFC_PPB_REG NAND_CONFIGURATION2_REG
+#define NFC_PPB_SHIFT 7
+#define NFC_PPB_MASK ~(3 << NFC_PPB_SHIFT)
-/*!
- * Defined the "complete" address input operations which may involve
- * more than one cycle of single address input operation.
- */
-enum nfc_addr_ops {
- ADDRESS_INPUT_READ_ID,
- ADDRESS_INPUT_READ_PAGE,
- ADDRESS_INPUT_PROGRAM_PAGE,
- ADDRESS_INPUT_ERASE_BLOCK,
+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_MASK = ~(0x7 << 4),
};
-enum nfc_page_area {
- NFC_SPARE_ONLY,
- NFC_MAIN_ONLY,
+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,
};
-enum {
- MXC_NAND_8_BIT = 8,
- MXC_NAND_16_BIT = 16,
-};
+#define wait_for_auto_prog_done()
-enum {
- NAND_SLC = 0,
- NAND_MLC = 1,
-};
+// Polls the NANDFC to wait for an operation to complete
+#define wait_op_done() CYG_MACRO_START \
+ u32 __nfc_stat = nfc_reg_read(NFC_IPC_REG); \
+ while (!(__nfc_stat & NFC_IPC_INT)) { \
+ __nfc_stat = nfc_reg_read(NFC_IPC_REG); \
+ } \
+ nfc_reg_write(__nfc_stat & ~NFC_IPC_INT, NFC_IPC_REG); \
+CYG_MACRO_END
+
+#if 1
+#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)
+{
+ nfc_printf(NFC_DEBUG_MAX, "%s: Writing %08x to %s[%04lx]\n", fn, val, reg,
+ (unsigned long)addr & 0x3fff);
+ writel(val, addr);
+}
-// read column 464-465 byte but only 464 for bad block marker
-#define BAD_BLK_MARKER_464 (NAND_MAIN_BUF3 + 464)
-// read column 4-5 byte, but only 5 is used for swapped main area data
-#define BAD_BLK_MARKER_SP_5 (NAND_SPAR_BUF3 + 4)
+#define nfc_reg_read(r) __nfc_reg_read((void *)(r), #r, __FUNCTION__)
+static inline u32 __nfc_reg_read(void *addr,
+ const char *reg, const char *fn)
+{
+ u32 val;
+ val = readl(addr);
+ nfc_printf(NFC_DEBUG_MAX, "%s: Read %08x from %s[%04lx]\n", fn, val, reg,
+ (unsigned long)addr & 0x3fff);
+ return val;
+}
-// Polls the NANDFC to wait for an operation to complete
-#define wait_op_done() \
- do { \
- volatile int mxc_nfc_wait_loop; \
- while ((readl(NFC_IPC_REG) & NFC_IPC_INT) == 0) \
- {for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++);} \
- write_nfc_ip_reg(0, NFC_IPC_REG); \
- } while (0)
-
-int nfc_read_region(u32 la, u32 maddr, int len);
-int nfc_program_region(u32 la, u32 maddr, int len);
-int nfc_erase_region(u32 la, int len);
+#define write_nfc_ip_reg(v, r) CYG_MACRO_START \
+ nfc_reg_write(NFC_IPC_CREQ, NFC_IPC_REG); \
+ while (!(nfc_reg_read(NFC_IPC_REG) & NFC_IPC_CACK)); \
+ __nfc_reg_write(v, (void *)(r), #r, __FUNCTION__); \
+ nfc_reg_write(0, NFC_IPC_REG); \
+CYG_MACRO_END
+#else
+#define nfc_reg_read(r) readl(r)
+#define nfc_reg_write(v, r) writel(v, r)
static void write_nfc_ip_reg(u32 val, u32 reg)
{
- volatile int mxc_nfc_wait_loop;
-
- writel(NFC_IPC_CREQ, NFC_IPC_REG);
- for (mxc_nfc_wait_loop = 0; mxc_nfc_wait_loop < 100; mxc_nfc_wait_loop++);
-
- writel(val, reg);
- writel(0, NFC_IPC_REG);
+ nfc_reg_write(NFC_IPC_CREQ, NFC_IPC_REG);
+ while (!(nfc_reg_read(NFC_IPC_REG) & NFC_IPC_CACK));
+ nfc_reg_write(val, reg);
+ nfc_reg_write(0, NFC_IPC_REG);
}
+#endif
/*!
* NAND flash data output operation (reading data from NAND flash)
- * @param buf_no internal ram buffer number that will contain data
- * to be outputted from the NAND flash after operation done
- * @param mode one of the mode defined in enum nfc_output_mode
- * @param ecc_en 1 - ecc enabled; 0 - ecc disabled
+ * @param buf_no internal ram buffer number that will contain data
+ * to be outputted from the NAND flash after operation done
+ * @param mode one of the mode defined in enum nfc_output_mode
+ * @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 = readl(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 = readl(NAND_CONFIGURATION1_REG);
-
- if (mode == FDO_SPARE_ONLY) {
- v = (v & ~0x31) | buf_no | NAND_CONFIGURATION1_SP_EN;
- } else {
- v = (v & ~0x31) | buf_no;
- }
-
- writel(v, NAND_CONFIGURATION1_REG);
-
- writel(mode & 0xFF, NAND_LAUNCH_REG);
- wait_op_done();
+ 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);
+ }
+
+ v = (nfc_reg_read(NAND_CONFIGURATION1_REG) & RAM_BUF_MASK) | buf_no;
+ if (mode == FDO_SPARE_ONLY) {
+ v |= NAND_CONFIGURATION1_SP_EN;
+ } else {
+ v &= ~NAND_CONFIGURATION1_SP_EN;
+ }
+ nfc_reg_write(v, NAND_CONFIGURATION1_REG);
+
+ nfc_reg_write(mode & 0xFF, NAND_LAUNCH_REG);
+ wait_op_done();
}
static void NFC_CMD_INPUT(u32 cmd)
{
- writel(cmd & 0xFFFF, NAND_ADD_CMD_REG);
- writel(NAND_LAUNCH_FCMD, NAND_LAUNCH_REG);
- wait_op_done();
+ nfc_reg_write(cmd & 0xFFFF, NAND_ADD_CMD_REG);
+ nfc_reg_write(NAND_LAUNCH_FCMD, NAND_LAUNCH_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;
}
/*!
* NAND flash data input operation (writing data to NAND flash)
- * @param buf_no internal ram buffer number containing data to be
- * written into the NAND flash
- * @param area NFC_SPARE_ONLY or NFC_MAIN_ONLY,
- * @param ecc_en 1 - ecc enabled; 0 - ecc disabled
+ * @param buf_no internal ram buffer number containing data to be
+ * written into the NAND flash
+ * @param area NFC_SPARE_ONLY or NFC_MAIN_ONLY,
+ * @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)
{
- u32 v = readl(NFC_FLASH_CONFIG2_REG);
-
- // setup config2 register for ECC enable or not
- 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);
- }
-
- // setup config1 register for ram buffer number, spare-only or not
- v = readl(NAND_CONFIGURATION1_REG);
-
- if (area == NFC_SPARE_ONLY) {
- v = (v & ~0x31) | buf_no | NAND_CONFIGURATION1_SP_EN;
- } else {
- v = (v & ~0x31) | buf_no;
- }
-
- writel(v, NAND_CONFIGURATION1_REG);
-
- // start operation
- writel(NAND_LAUNCH_FDI, NAND_LAUNCH_REG);
- wait_op_done();
+ u32 v = nfc_reg_read(NFC_FLASH_CONFIG2_REG);
+
+ // setup config2 register for ECC enable or not
+ 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);
+ }
+
+ // setup config1 register for ram buffer number, spare-only or not
+ v = (nfc_reg_read(NAND_CONFIGURATION1_REG) & RAM_BUF_MASK) | buf_no;
+ if (area == NFC_SPARE_ONLY) {
+ v |= NAND_CONFIGURATION1_SP_EN;
+ } else {
+ v &= ~NAND_CONFIGURATION1_SP_EN;
+ }
+ nfc_reg_write(v, NAND_CONFIGURATION1_REG);
+
+ // start operation
+ nfc_reg_write(NAND_LAUNCH_FDI, NAND_LAUNCH_REG);
+ wait_op_done();
}
static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no)
{
- u32 v;
+ u32 v;
- // setup config1 register for ram buffer number, spare-only or not
- v = readl(NAND_CONFIGURATION1_REG);
- v = (v & ~0x30) | buf_no;
- writel(v, NAND_CONFIGURATION1_REG);
+ // setup config1 register for ram buffer number, spare-only or not
+ v = (nfc_reg_read(NAND_CONFIGURATION1_REG) & RAM_BUF_MASK) | buf_no;
+ nfc_reg_write(v, NAND_CONFIGURATION1_REG);
- // start operation
- writel(NAND_LAUNCH_FDI, NAND_LAUNCH_REG);
- wait_op_done();
+ // start operation
+ nfc_reg_write(NAND_LAUNCH_FDI, NAND_LAUNCH_REG);
+ wait_op_done();
}
/*!
*/
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()
+}
+
+static void NFC_SET_NFC_ACTIVE_CS(u32 cs_line)
+{
+ // not needed.
}
/*!
* Issue the address input operation
- * @param addr the address for the address input operation
+ * @param addr the address for the address input operation
*/
static void NFC_ADDR_INPUT(u32 addr)
{
- writel((addr & ((1 << ADDR_INPUT_SIZE) - 1)) << 16, NAND_ADD_CMD_REG);
- writel(NAND_LAUNCH_FADD, NAND_LAUNCH_REG);
- wait_op_done();
+#if 0
+ if (nfc_debug) {
+ diag_printf("add = 0x%08x, at 0x%08lx\n",
+ (addr & 0xFF) << 16, NAND_ADD_CMD_REG);
+ diag_printf("NAND_LAUNCH_FADD=%08x, NAND_LAUNCH_REG=%08lx\n",
+ NAND_LAUNCH_FADD, NAND_LAUNCH_REG);
+ }
+#endif
+ nfc_reg_write((addr & 0xFF) << 16, NAND_ADD_CMD_REG);
+ nfc_reg_write(NAND_LAUNCH_FADD, NAND_LAUNCH_REG);
+ wait_op_done();
}
+#define NFC_ARCH_INIT()
+#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_V2_H_