/******************************************************************************* * NFC_CopyBackWrite * * Description : copyback write one page data inside flash in single plane mode or multi plane mode * Arguments : *cwcmd -- the copyback read command sequence list head. rb_wait_mode -- 0 = do not care rb, 1 = set rb interrupt and do not wait rb ready. * Returns : 0 = success. -1 = fail. * Notes : the unit must be page. ********************************************************************************/ __s32 NFC_CopyBackWrite(NFC_CMD_LIST *cwcmd, __u8 rb_wait_mode) { __s32 ret; _enter_nand_critical(); ret = nfc_set_cmd_register(cwcmd); if (ret){ _exit_nand_critical(); return ret; } _wait_twb(); ret = _wait_cmdfifo_free(); ret |= _wait_cmd_finish(); _exit_nand_critical(); return ret; }
__s32 NFC_Write_Wait( NFC_CMD_LIST *wcmd, void *mainbuf, void *sparebuf, __u8 dma_wait_mode, __u8 rb_wait_mode, __u8 page_mode) { __s32 ret; NAND_WaitDmaFinish(); ret = _wait_dma_end(1, (__u32)mainbuf, pagesize); if (ret) return ret; _wait_twb(); _wait_cmdfifo_free(); _wait_cmd_finish(); /*disable ecc*/ _disable_ecc(); /*switch to ahb*/ NFC_WRITE_REG(NFC_REG_CTL, (NFC_READ_REG(NFC_REG_CTL)) & (~NFC_RAM_METHOD)); _exit_nand_critical(); return ret; }
/******************************************************************************* * NFC_Write * * Description : write one page data into flash in single plane mode. * Arguments : *wcmd -- the write command sequence list head。 * *mainbuf -- point to data buffer address, it must be four bytes align. * *sparebuf -- point to spare buffer address. * dma_wait_mode -- how to deal when dma start, 0 = wait till dma finish, 1 = dma interrupt was set and now sleep till interrupt occurs. * rb_wait_mode -- 0 = do not care rb, 1 = set rb interrupt and do not wait rb ready. * page_mode -- 0 = common command, 1 = page command. * Returns : 0 = success. -1 = fail. * Notes : the unit must be page, so if page_mode is not 1, return fail,the function exits without checking status, if the commands do not fetch data,ecc is not neccesary. ********************************************************************************/ __s32 NFC_Write( NFC_CMD_LIST *wcmd, void *mainbuf, void *sparebuf, __u8 dma_wait_mode, __u8 rb_wait_mode, __u8 page_mode) { __s32 ret; __s32 i; __u32 cfg; __u32 program_cmd,random_program_cmd; NFC_CMD_LIST *cur_cmd,*program_addr_cmd; if (page_mode == 0){ return -1; } ret = 0; _enter_nand_critical(); /*write in page_mode*/ program_addr_cmd = wcmd; cur_cmd = wcmd; cur_cmd = cur_cmd->next; random_program_cmd = cur_cmd->value; cur_cmd = cur_cmd->next; program_cmd = cur_cmd->value; //access NFC internal RAM by DMA bus NFC_WRITE_REG(NFC_REG_CTL, (NFC_READ_REG(NFC_REG_CTL)) | NFC_RAM_METHOD); /*set dma and run*/ // if (NFC_IS_SDRAM((__u32)mainbuf)) // attr = 0x2930281; // else // attr = 0x2930280; _dma_config_start(1, (__u32)mainbuf, pagesize); /*wait cmd fifo free*/ ret = _wait_cmdfifo_free(); if (ret){ _exit_nand_critical(); return ret; } /*set NFC_REG_CNT*/ NFC_WRITE_REG(NFC_REG_CNT,1024); /*set NFC_REG_RCMD_SET*/ cfg = 0; cfg |= (program_cmd & 0xff); cfg |= ((random_program_cmd & 0xff) << 8); NFC_WRITE_REG(NFC_REG_WCMD_SET, cfg); /*set NFC_REG_SECTOR_NUM*/ NFC_WRITE_REG(NFC_REG_SECTOR_NUM, pagesize/1024); /*set user data*/ for (i = 0; i < pagesize/1024; i++){ NFC_WRITE_REG(NFC_REG_USER_DATA(i), *((__u32 *)sparebuf + i) ); } /*set addr*/ _set_addr(program_addr_cmd->addr,program_addr_cmd->addr_cycle); /*set NFC_REG_CMD*/ cfg = 0; /*set sequence mode*/ //cfg |= 0x1<<25; cfg |= program_addr_cmd->value; cfg |= ( (program_addr_cmd->addr_cycle - 1) << 16); //cfg |= (NFC_SEND_ADR | NFC_ACCESS_DIR | NFC_DATA_TRANS | NFC_SEND_CMD | NFC_WAIT_FLAG | NFC_DATA_SWAP_METHOD); cfg |= (NFC_SEND_ADR | NFC_ACCESS_DIR | NFC_DATA_TRANS | NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_SWAP_METHOD); cfg |= ((__u32)0x2 << 30);//page command if (pagesize/1024 == 1) cfg |= NFC_SEQ; /*enable ecc*/ _enable_ecc(1); NFC_WRITE_REG(NFC_REG_CMD,cfg); NAND_WaitDmaFinish(); _wait_twb(); _wait_cmdfifo_free(); _wait_cmd_finish(); /*start dma?*/ /*if dma mode is wait*/ if(0 == dma_wait_mode){ ret = _wait_dma_end(); } /*disable ecc*/ _disable_ecc(); /*switch to ahb*/ NFC_WRITE_REG(NFC_REG_CTL, (NFC_READ_REG(NFC_REG_CTL)) & (~NFC_RAM_METHOD)); _exit_nand_critical(); return ret; }
__s32 NFC_Write_Seq( NFC_CMD_LIST *wcmd, void *mainbuf, void *sparebuf, __u8 dma_wait_mode, __u8 rb_wait_mode, __u8 page_mode) { __s32 ret; __s32 i; __u32 cfg; __u32 page_size_temp, ecc_mode_temp,page_size_set,ecc_set; __u32 program_cmd,random_program_cmd; NFC_CMD_LIST *cur_cmd,*program_addr_cmd; if (page_mode == 0){ return -1; } ret = 0; _enter_nand_critical(); /*write in page_mode*/ program_addr_cmd = wcmd; cur_cmd = wcmd; cur_cmd = cur_cmd->next; random_program_cmd = cur_cmd->value; cur_cmd = cur_cmd->next; program_cmd = cur_cmd->value; //access NFC internal RAM by DMA bus NFC_WRITE_REG(NFC_REG_CTL, (NFC_READ_REG(NFC_REG_CTL)) | NFC_RAM_METHOD); //set pagesize to 8K for burn boot0 lsb mode page_size_temp = (NFC_READ_REG(NFC_REG_CTL) & 0xf00)>>8; NFC_WRITE_REG(NFC_REG_CTL, ((NFC_READ_REG(NFC_REG_CTL)) & (~NFC_PAGE_SIZE))| (0x3<<8)); page_size_set = 8192; //fix pagesize 8k to burn boot1.bin for hynix 2x and 2y nm flash _dma_config_start(1, (__u32)mainbuf, page_size_set); /*wait cmd fifo free*/ ret = _wait_cmdfifo_free(); if (ret){ _exit_nand_critical(); return ret; } /*set NFC_REG_CNT*/ NFC_WRITE_REG(NFC_REG_CNT,1024); /*set NFC_REG_RCMD_SET*/ cfg = 0; cfg |= (program_cmd & 0xff); cfg |= ((random_program_cmd & 0xff) << 8); NFC_WRITE_REG(NFC_REG_WCMD_SET, cfg); /*set NFC_REG_SECTOR_NUM*/ NFC_WRITE_REG(NFC_REG_SECTOR_NUM, page_size_set/1024); /*set user data*/ for (i = 0; i < page_size_set/1024; i++){ NFC_WRITE_REG(NFC_REG_USER_DATA(i), *((__u32 *)sparebuf + i) ); } /*set addr*/ _set_addr(program_addr_cmd->addr,program_addr_cmd->addr_cycle); /*set NFC_REG_CMD*/ cfg = 0; /*set sequence mode*/ cfg |= 0x1<<25; cfg |= program_addr_cmd->value; cfg |= ( (program_addr_cmd->addr_cycle - 1) << 16); //cfg |= (NFC_SEND_ADR | NFC_ACCESS_DIR | NFC_DATA_TRANS | NFC_SEND_CMD | NFC_WAIT_FLAG | NFC_DATA_SWAP_METHOD); cfg |= (NFC_SEND_ADR | NFC_ACCESS_DIR | NFC_DATA_TRANS | NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_SWAP_METHOD); cfg |= ((__u32)0x2 << 30);//page command /*enable ecc*/ _enable_ecc(1); /*set ecc to specified ecc*/ ecc_mode_temp = (NFC_READ_REG(NFC_REG_ECC_CTL) & 0xf000)>>12; if(ecc_mode_temp>=4) //change for hynix 2y nm flash ecc_set = 0x4; else//change for hynix 2x nm flash ecc_set = 0x1; NFC_WRITE_REG(NFC_REG_ECC_CTL, ((NFC_READ_REG(NFC_REG_ECC_CTL) & (~NFC_ECC_MODE))|(ecc_set<<12) )); NFC_WRITE_REG(NFC_REG_CMD,cfg); NAND_WaitDmaFinish(); _wait_twb(); _wait_cmdfifo_free(); _wait_cmd_finish(); /*start dma?*/ /*if dma mode is wait*/ // if(0 == dma_wait_mode){ // ret = _wait_dma_end(); // } /*disable ecc*/ _disable_ecc(); /*set ecc to original value*/ NFC_WRITE_REG(NFC_REG_ECC_CTL, (NFC_READ_REG(NFC_REG_ECC_CTL) & (~NFC_ECC_MODE))|(ecc_mode_temp<<12)); /*set pagesize to original value*/ NFC_WRITE_REG(NFC_REG_CTL, ((NFC_READ_REG(NFC_REG_CTL)) & (~NFC_PAGE_SIZE)) | (page_size_temp<<8)); /*switch to ahb*/ NFC_WRITE_REG(NFC_REG_CTL, (NFC_READ_REG(NFC_REG_CTL)) & (~NFC_RAM_METHOD)); _exit_nand_critical(); return ret; }
__s32 NFC_Write_1K( NFC_CMD_LIST *wcmd, void *mainbuf, void *sparebuf, __u8 dma_wait_mode, __u8 rb_wait_mode, __u8 page_mode) { __s32 ret; __s32 i; __u32 cfg; __u32 page_size_temp, ecc_mode_temp; __u32 program_cmd,random_program_cmd; NFC_CMD_LIST *cur_cmd,*program_addr_cmd; if (page_mode == 0){ return -1; } ret = 0; _enter_nand_critical(); /*write in page_mode*/ program_addr_cmd = wcmd; cur_cmd = wcmd; cur_cmd = cur_cmd->next; random_program_cmd = cur_cmd->value; cur_cmd = cur_cmd->next; program_cmd = cur_cmd->value; //access NFC internal RAM by DMA bus NFC_WRITE_REG(NFC_REG_CTL, (NFC_READ_REG(NFC_REG_CTL)) | NFC_RAM_METHOD); //set pagesize to 1K page_size_temp = (NFC_READ_REG(NFC_REG_CTL) & 0xf00)>>8; NFC_WRITE_REG(NFC_REG_CTL, ((NFC_READ_REG(NFC_REG_CTL)) & (~NFC_PAGE_SIZE))| (0x0<<8)); _dma_config_start(1, (__u32)mainbuf, 1024); /*wait cmd fifo free*/ ret = _wait_cmdfifo_free(); if (ret){ _exit_nand_critical(); return ret; } /*set NFC_REG_CNT*/ NFC_WRITE_REG(NFC_REG_CNT,1024); /*set NFC_REG_RCMD_SET*/ cfg = 0; cfg |= (program_cmd & 0xff); cfg |= ((random_program_cmd & 0xff) << 8); NFC_WRITE_REG(NFC_REG_WCMD_SET, cfg); /*set NFC_REG_SECTOR_NUM*/ NFC_WRITE_REG(NFC_REG_SECTOR_NUM, 1024/1024); /*set user data*/ for (i = 0; i < 1024/1024; i++){ NFC_WRITE_REG(NFC_REG_USER_DATA(i), *((__u32 *)sparebuf + i) ); } /*set addr*/ _set_addr(program_addr_cmd->addr,program_addr_cmd->addr_cycle); /*set NFC_REG_CMD*/ cfg = 0; /*set sequence mode*/ cfg |= 0x1<<25; cfg |= program_addr_cmd->value; cfg |= ( (program_addr_cmd->addr_cycle - 1) << 16); //cfg |= (NFC_SEND_ADR | NFC_ACCESS_DIR | NFC_DATA_TRANS | NFC_SEND_CMD | NFC_WAIT_FLAG | NFC_DATA_SWAP_METHOD); cfg |= (NFC_SEND_ADR | NFC_ACCESS_DIR | NFC_DATA_TRANS | NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_SWAP_METHOD); cfg |= ((__u32)0x2 << 30);//page command if (pagesize/1024 == 1) cfg |= NFC_SEQ; /*enable ecc*/ _enable_ecc(1); /*set ecc to 64-bit ecc*/ ecc_mode_temp = (NFC_READ_REG(NFC_REG_ECC_CTL) & 0xf000)>>12; NFC_WRITE_REG(NFC_REG_ECC_CTL, ((NFC_READ_REG(NFC_REG_ECC_CTL) & (~NFC_ECC_MODE))|(0x8<<12) )); NFC_WRITE_REG(NFC_REG_CMD,cfg); NAND_WaitDmaFinish(); ret = _wait_dma_end(1, (__u32)mainbuf, 1024); if (ret) return ret; _wait_twb(); _wait_cmdfifo_free(); _wait_cmd_finish(); /*disable ecc*/ _disable_ecc(); /*set ecc to original value*/ NFC_WRITE_REG(NFC_REG_ECC_CTL, (NFC_READ_REG(NFC_REG_ECC_CTL) & (~NFC_ECC_MODE))|(ecc_mode_temp<<12)); /*set pagesize to original value*/ NFC_WRITE_REG(NFC_REG_CTL, ((NFC_READ_REG(NFC_REG_CTL)) & (~NFC_PAGE_SIZE)) | (page_size_temp<<8)); /*switch to ahb*/ NFC_WRITE_REG(NFC_REG_CTL, (NFC_READ_REG(NFC_REG_CTL)) & (~NFC_RAM_METHOD)); _exit_nand_critical(); return ret; }