diff options
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c index 637c085a75..07eb344040 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | |||
@@ -215,10 +215,9 @@ uint32_t nand_wait_status_ready(uint32_t bank) | |||
215 | return nand_send_cmd(NAND_CMD_READ); | 215 | return nand_send_cmd(NAND_CMD_READ); |
216 | } | 216 | } |
217 | 217 | ||
218 | uint32_t nand_transfer_data(uint32_t bank, uint32_t direction, | 218 | void nand_transfer_data_start(uint32_t bank, uint32_t direction, |
219 | void* buffer, uint32_t size) | 219 | void* buffer, uint32_t size) |
220 | { | 220 | { |
221 | long timeout = current_tick + HZ / 50; | ||
222 | nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA); | 221 | nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA); |
223 | FMDNUM = size - 1; | 222 | FMDNUM = size - 1; |
224 | FMCTRL1 = FMCTRL1_DOREADDATA << direction; | 223 | FMCTRL1 = FMCTRL1_DOREADDATA << direction; |
@@ -232,6 +231,11 @@ uint32_t nand_transfer_data(uint32_t bank, uint32_t direction, | |||
232 | DMATCNT3 = (size >> 4) - 1; | 231 | DMATCNT3 = (size >> 4) - 1; |
233 | clean_dcache(); | 232 | clean_dcache(); |
234 | DMACOM3 = 4; | 233 | DMACOM3 = 4; |
234 | } | ||
235 | |||
236 | uint32_t nand_transfer_data_collect(uint32_t direction) | ||
237 | { | ||
238 | long timeout = current_tick + HZ / 50; | ||
235 | while ((DMAALLST & DMAALLST_DMABUSY3)) | 239 | while ((DMAALLST & DMAALLST_DMABUSY3)) |
236 | if (nand_timeout(timeout)) return 1; | 240 | if (nand_timeout(timeout)) return 1; |
237 | if (!direction) invalidate_dcache(); | 241 | if (!direction) invalidate_dcache(); |
@@ -241,17 +245,29 @@ uint32_t nand_transfer_data(uint32_t bank, uint32_t direction, | |||
241 | return 0; | 245 | return 0; |
242 | } | 246 | } |
243 | 247 | ||
244 | uint32_t ecc_decode(uint32_t size, void* databuffer, void* sparebuffer) | 248 | uint32_t nand_transfer_data(uint32_t bank, uint32_t direction, |
249 | void* buffer, uint32_t size) | ||
250 | { | ||
251 | nand_transfer_data_start(bank, direction, buffer, size); | ||
252 | uint32_t rc = nand_transfer_data_collect(direction); | ||
253 | return rc; | ||
254 | } | ||
255 | |||
256 | void ecc_start(uint32_t size, void* databuffer, void* sparebuffer, uint32_t type) | ||
245 | { | 257 | { |
246 | mutex_lock(&ecc_mtx); | 258 | mutex_lock(&ecc_mtx); |
247 | long timeout = current_tick + HZ / 50; | ||
248 | ECC_INT_CLR = 1; | 259 | ECC_INT_CLR = 1; |
249 | SRCPND = INTMSK_ECC; | 260 | SRCPND = INTMSK_ECC; |
250 | ECC_UNK1 = size; | 261 | ECC_UNK1 = size; |
251 | ECC_DATA_PTR = (uint32_t)databuffer; | 262 | ECC_DATA_PTR = (uint32_t)databuffer; |
252 | ECC_SPARE_PTR = (uint32_t)sparebuffer; | 263 | ECC_SPARE_PTR = (uint32_t)sparebuffer; |
253 | clean_dcache(); | 264 | clean_dcache(); |
254 | ECC_CTRL = ECCCTRL_STARTDECODING; | 265 | ECC_CTRL = type; |
266 | } | ||
267 | |||
268 | uint32_t ecc_collect(void) | ||
269 | { | ||
270 | long timeout = current_tick + HZ / 50; | ||
255 | while (!(SRCPND & INTMSK_ECC)) | 271 | while (!(SRCPND & INTMSK_ECC)) |
256 | if (nand_timeout(timeout)) return ecc_unlock(1); | 272 | if (nand_timeout(timeout)) return ecc_unlock(1); |
257 | invalidate_dcache(); | 273 | invalidate_dcache(); |
@@ -260,23 +276,18 @@ uint32_t ecc_decode(uint32_t size, void* databuffer, void* sparebuffer) | |||
260 | return ecc_unlock(ECC_RESULT); | 276 | return ecc_unlock(ECC_RESULT); |
261 | } | 277 | } |
262 | 278 | ||
279 | uint32_t ecc_decode(uint32_t size, void* databuffer, void* sparebuffer) | ||
280 | { | ||
281 | ecc_start(size, databuffer, sparebuffer, ECCCTRL_STARTDECODING); | ||
282 | uint32_t rc = ecc_collect(); | ||
283 | return rc; | ||
284 | } | ||
285 | |||
263 | uint32_t ecc_encode(uint32_t size, void* databuffer, void* sparebuffer) | 286 | uint32_t ecc_encode(uint32_t size, void* databuffer, void* sparebuffer) |
264 | { | 287 | { |
265 | mutex_lock(&ecc_mtx); | 288 | ecc_start(size, databuffer, sparebuffer, ECCCTRL_STARTENCODING); |
266 | long timeout = current_tick + HZ / 50; | 289 | ecc_collect(); |
267 | ECC_INT_CLR = 1; | 290 | return 0; |
268 | SRCPND = INTMSK_ECC; | ||
269 | ECC_UNK1 = size; | ||
270 | ECC_DATA_PTR = (uint32_t)databuffer; | ||
271 | ECC_SPARE_PTR = (uint32_t)sparebuffer; | ||
272 | clean_dcache(); | ||
273 | ECC_CTRL = ECCCTRL_STARTENCODING; | ||
274 | while (!(SRCPND & INTMSK_ECC)) | ||
275 | if (nand_timeout(timeout)) return ecc_unlock(1); | ||
276 | invalidate_dcache(); | ||
277 | ECC_INT_CLR = 1; | ||
278 | SRCPND = INTMSK_ECC; | ||
279 | return ecc_unlock(0); | ||
280 | } | 291 | } |
281 | 292 | ||
282 | uint32_t nand_check_empty(uint8_t* buffer) | 293 | uint32_t nand_check_empty(uint8_t* buffer) |