X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-redboot.git;a=blobdiff_plain;f=packages%2Fdevs%2Fflash%2Farm%2Fmxc%2Fv2_0%2Finclude%2Fmxc_nfc_v2.h;h=da2b424293d6c96023d11b2b8970da0488b16ad5;hp=43c793826880465d53621a86e7e309db27433e22;hb=7a4ea0a4d67744fd3f6b5f207d857005fc707b46;hpb=f0c1bd5d9f8457be4a43912a28ca2df207a7f5a4 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 43c79382..da2b4242 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,233 +55,217 @@ #include #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(); } /*! @@ -289,18 +273,39 @@ static void NFC_DATA_INPUT_2k(enum nfc_internal_buf buf_no) */ 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_