static int controller_queue_rb_irq(struct hw_controller *controller, unsigned char chipnr) { int ret = 0, timeout = 0; if(chipnr != NAND_CHIP_UNDEFINE){ //skip dma operation controller->select_chip(controller, chipnr); } init_completion(&controller_rb_completion); controller_open_interrupt(); NFC_SEND_CMD_IDLE(controller->chip_selected, NAND_TWB_TIME_CYCLE); controller->cmd_ctrl(controller, NAND_CMD_STATUS, NAND_CTRL_CLE); NFC_SEND_CMD_IDLE(controller->chip_selected, NAND_TWB_TIME_CYCLE); smp_rmb(); smp_wmb(); NFC_SEND_CMD_RB_IRQ(18); //NFC_SEND_CMD_IDLE(controller->chip_selected, NAND_TWB_TIME_CYCLE); timeout = wait_for_completion_timeout(&controller_rb_completion, 200); if(timeout == 0){ aml_nand_msg("***nand irq timeout here"); ret = -NAND_BUSY_FAILURE; } controller_close_interrupt(); return ret; }
STATIC_PREFIX int nf_read_dma(unsigned * dest, volatile unsigned * info,unsigned size,t_ecc_mode ecc_mode) { unsigned cnt,i; if(ecc_mode!=NAND_ECC_BCH16) return -1; if(size&0x1ff) return -1; // the size must be aligned with 512 cnt=size>>9; for(i=0;i<cnt;i++) { info[i]=0; } NFC_SET_DADDR(dest); NFC_SET_IADDR(&info[0]); NFC_SEND_CMD_N2M(size,ecc_mode); NFC_SEND_CMD_IDLE(CE0,5); NFC_SEND_CMD_IDLE(CE0,0); while (NFC_CMDFIFO_SIZE() > 0); // all cmd is finished for(i=0;i<cnt;i++) { while((NAND_INFO_DONE(info[i]))==0); if(NAND_ECC_ENABLE(info[i])&&(NAND_ECC_FAIL(info[i]))) return -1; if(NAND_INFO_DATA_2INFO(info[i])!=0x55aa) return -2; } return 0; }
/** page_mode : 0, small page ; 1 large page */ STATIC_PREFIX int nf_send_read_cmd(unsigned page_off,unsigned page_mode) { while (NFC_CMDFIFO_SIZE() > 15); NFC_SEND_CMD_CLE(CE0,0); //Send NAND read start command NFC_SEND_CMD_ALE(CE0,0); // Send Address if(page_mode) NFC_SEND_CMD_ALE(CE0,0); NFC_SEND_CMD_ALE(CE0,page_off&0xff); NFC_SEND_CMD_ALE(CE0,(page_off&0xff00)>>8); NFC_SEND_CMD_ALE(CE0,(page_off&0xff0000)>>16); if(page_mode) NFC_SEND_CMD_CLE(CE0,0x30); /** waiting for tWB **/ NFC_SEND_CMD_IDLE(CE0,5); // tWB NFC_SEND_CMD_RB(CE0,14); if(((NFC_INFO_GET()>>26)&1)) { serial_puts("BUG RB CMD\n"); while(!((NFC_INFO_GET()>>26)&1)); } NFC_SEND_CMD_IDLE(CE0,0); while (NFC_CMDFIFO_SIZE() > 0); // all cmd is finished return 0; }
static int controller_queue_rb_irq(struct hw_controller *controller, unsigned char chipnr) { int ret = 0, timeout = 0; if (chipnr != NAND_CHIP_UNDEFINE)/* skip dma operation */ controller->select_chip(controller, chipnr); reinit_completion(&rb_complete); controller_open_interrupt(controller); NFC_SEND_CMD_IDLE(controller, NAND_TWB_TIME_CYCLE); controller->cmd_ctrl(controller, NAND_CMD_STATUS, NAND_CTRL_CLE); NFC_SEND_CMD_IDLE(controller, NAND_TWB_TIME_CYCLE); /* */ smp_rmb(); /* */ smp_wmb(); NFC_SEND_CMD_RB_IRQ(controller, 18); /* NFC_SEND_CMD_IDLE(controller, NAND_TWB_TIME_CYCLE); */ timeout = wait_for_completion_timeout(&rb_complete, 800); if (timeout == 0) { aml_nand_msg("***[nand] rb irq timeout"); ret = -NAND_BUSY_FAILURE; } controller_close_interrupt(controller); return ret; }
static int controller_select_chip(struct hw_controller *controller, unsigned char chipnr) { int ret = 0; switch (chipnr) { case 0: case 1: case 2: case 3: controller->chip_selected = controller->ce_enable[chipnr]; controller->rb_received = controller->rb_enable[chipnr]; #ifdef AML_NAND_UBOOT for (i=0; i < controller->chip_num; i++) { pinmux_select_chip(controller->ce_enable[i], controller->rb_enable[i], ((controller->option & NAND_CTRL_NONE_RB) == 0)); } #endif NFC_SEND_CMD_IDLE(controller->chip_selected, 0); break; default: BUG(); controller->chip_selected = CE_NOT_SEL; ret = -NAND_SELECT_CHIP_FAILURE; aml_nand_msg("failed"); break; } return ret; }
void nf_erase(void) { int i; nf_cntl_init(romboot_info); for(i=0;i<4;i++) { NFC_SEND_CMD_CLE(CE0,0x60); NFC_SEND_CMD_ALE(CE0,0); NFC_SEND_CMD_ALE(CE0,i); NFC_SEND_CMD_ALE(CE0,0); NFC_SEND_CMD_CLE(CE0,0xd0); NFC_SEND_CMD_RB(CE0,0); } NFC_SEND_CMD_IDLE(CE0,0); // FIFO cleanup NFC_SEND_CMD_IDLE(CE0,0); // FIFO cleanup while(NFC_CMDFIFO_SIZE()>0); // wait until all command is finished }
STATIC_PREFIX void nf_reset(t_nf_ce ce) { NFC_SEND_CMD(1<<31); NFC_SEND_CMD_IDLE(ce,0); // FIFO cleanup NFC_SEND_CMD_CLE(ce,0xff); //Send reset command NFC_SEND_CMD_IDLE(ce,10); //Wait tWB NFC_SEND_CMD_RB(ce,15); //Wait Busy Signal NFC_SEND_CMD_IDLE(ce,0); // FIFO cleanup NFC_SEND_CMD_IDLE(ce,0); // FIFO cleanup while(NFC_CMDFIFO_SIZE()>0) // wait until all command is finished { if(NFC_CHECEK_RB_TIMEOUT()) // RB time out break; } while(!((NFC_INFO_GET()>>26)&1)); }
static int controller_select_chip(struct hw_controller *controller, unsigned char chipnr) { int ret = 0; switch (chipnr) { case 0: case 1: case 2: case 3: controller->chip_selected = controller->ce_enable[chipnr]; controller->rb_received = controller->rb_enable[chipnr]; NFC_SEND_CMD_IDLE(controller, 0); break; default: BUG(); controller->chip_selected = CE_NOT_SEL; ret = -NAND_SELECT_CHIP_FAILURE; aml_nand_msg("failed"); break; } return ret; }
static int controller_quene_rb(struct hw_controller *controller, unsigned char chipnr) { unsigned time_out_limit, time_out_cnt = 0; struct amlnand_chip *aml_chip = controller->aml_chip; int ret = 0; if(aml_chip->state == CHIP_RESETING){ time_out_limit = AML_NAND_ERASE_BUSY_TIMEOUT; } else if(aml_chip->state == CHIP_WRITING){ time_out_limit = AML_NAND_WRITE_BUSY_TIMEOUT; } else{ time_out_limit = AML_NAND_READ_BUSY_TIMEOUT; } //aml_nand_dbg("chipnr =%d",chipnr); controller->select_chip(controller, chipnr); NFC_SEND_CMD_IDLE(controller->chip_selected, 0); NFC_SEND_CMD_IDLE(controller->chip_selected, 0); while(NFC_CMDFIFO_SIZE() > 0); #if 0 NFC_SEND_CMD_RB(aml_chip->chip_enable, 20); NFC_SEND_CMD_IDLE(aml_chip->chip_selected, 0); NFC_SEND_CMD_IDLE(aml_chip->chip_selected, 0); do { if (NFC_CMDFIFO_SIZE() <= 0) break; }while (time_out_cnt++ <= AML_DMA_BUSY_TIMEOUT); #endif //udelay(2); if (controller->option & NAND_CTRL_NONE_RB) { controller->cmd_ctrl(controller, NAND_CMD_STATUS, NAND_CTRL_CLE); //aml_nand_dbg("controller->chip_selected =%d",controller->chip_selected); NFC_SEND_CMD_IDLE(controller->chip_selected, NAND_TWHR_TIME_CYCLE); do{ //udelay(chip->chip_delay); if ((int)controller->readbyte(controller) & NAND_STATUS_READY) break; udelay(1); }while(time_out_cnt++ <= time_out_limit); //200ms max } else{ do{ if (NFC_GET_RB_STATUS(controller->rb_received)) break; udelay(2); }while(time_out_cnt++ <= time_out_limit); } if(time_out_cnt >= time_out_limit) ret = -NAND_BUSY_FAILURE; return ret; }