static int transferToFlash(void* buffer, int size) { int controller = 0; int channel = 0; if((((uint32_t)buffer) & 0x3) != 0) { // the buffer needs to be aligned for DMA, last two bits have to be clear return ERROR_ALIGN; } SET_REG(NAND + NAND_CONFIG, GET_REG(NAND + NAND_CONFIG) | (1 << NAND_CONFIG_DMASETTINGSHIFT)); SET_REG(NAND + NAND_TRANSFERSIZE, size - 1); SET_REG(NAND + NAND_CON, 0x7F4); CleanCPUDataCache(); dma_request(DMA_MEMORY, 4, 4, DMA_NAND, 4, 4, &controller, &channel, NULL); dma_perform((uint32_t)buffer, DMA_NAND, size, 0, &controller, &channel); if(dma_finish(controller, channel, 500) != 0) { bufferPrintf("nand: dma timed out\r\n"); return ERROR_TIMEOUT; } if(wait_for_status_bit_3(500) != 0) { bufferPrintf("nand: waiting for status bit 3 timed out\r\n"); return ERROR_TIMEOUT; } SET_REG(NAND + NAND_CON, NAND_CON_SETTING1); CleanAndInvalidateCPUDataCache(); return 0; }
static int transferToFlash(void* buffer, int size) { int controller = 0; int channel = 0; if((((uint32_t)buffer) & 0x3) != 0) { // the buffer needs to be aligned for DMA, last two bits have to be clear return ERROR_ALIGN; } SET_REG(NAND + FMCTRL0, GET_REG(NAND + FMCTRL0) | (1 << FMCTRL0_DMASETTINGSHIFT)); SET_REG(NAND + FMDNUM, size - 1); SET_REG(NAND + FMCTRL1, 0x7F4); CleanCPUDataCache(); dma_request(DMA_MEMORY, 4, 4, DMA_NAND, 4, 4, &controller, &channel, NULL); dma_perform((uint32_t)buffer, DMA_NAND, size, 0, &controller, &channel); if(dma_finish(controller, channel, 500) != 0) { bufferPrintf("nand: dma timed out\r\n"); return ERROR_TIMEOUT; } if(wait_for_transfer_done(500) != 0) { bufferPrintf("nand: waiting for transfer done timed out\r\n"); return ERROR_TIMEOUT; } SET_REG(NAND + FMCTRL1, FMCTRL1_FLUSHFIFOS); CleanAndInvalidateCPUDataCache(); return 0; }
static void ecc_perform(int setting, int sectors, uint8_t* sectorData, uint8_t* eccData) { SET_REG(NANDECC + NANDECC_CLEARINT, 1); SET_REG(NANDECC + NANDECC_SETUP, ((sectors - 1) & 0x3) | setting); SET_REG(NANDECC + NANDECC_DATA, (uint32_t) sectorData); SET_REG(NANDECC + NANDECC_ECC, (uint32_t) eccData); CleanCPUDataCache(); SET_REG(NANDECC + NANDECC_START, 1); }