summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2010-03-13 21:38:18 +0000
committerMichael Sparmann <theseven@rockbox.org>2010-03-13 21:38:18 +0000
commitaf77b1842ced33af99318f5cb24cd24718c78639 (patch)
tree9328e90c93c018494fed616f9caeca32e4f17b89 /firmware
parent0d6784fee21d6d4f0be9887c35d40bca1aadf81b (diff)
Nano2G lowlevel NAND operation transaction splitting support
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25152 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c53
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)
return nand_send_cmd(NAND_CMD_READ);
}
-uint32_t nand_transfer_data(uint32_t bank, uint32_t direction,
- void* buffer, uint32_t size)
+void nand_transfer_data_start(uint32_t bank, uint32_t direction,
+ void* buffer, uint32_t size)
{
- long timeout = current_tick + HZ / 50;
nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA);
FMDNUM = size - 1;
FMCTRL1 = FMCTRL1_DOREADDATA << direction;
@@ -232,6 +231,11 @@ uint32_t nand_transfer_data(uint32_t bank, uint32_t direction,
DMATCNT3 = (size >> 4) - 1;
clean_dcache();
DMACOM3 = 4;
+}
+
+uint32_t nand_transfer_data_collect(uint32_t direction)
+{
+ long timeout = current_tick + HZ / 50;
while ((DMAALLST & DMAALLST_DMABUSY3))
if (nand_timeout(timeout)) return 1;
if (!direction) invalidate_dcache();
@@ -241,17 +245,29 @@ uint32_t nand_transfer_data(uint32_t bank, uint32_t direction,
return 0;
}
-uint32_t ecc_decode(uint32_t size, void* databuffer, void* sparebuffer)
+uint32_t nand_transfer_data(uint32_t bank, uint32_t direction,
+ void* buffer, uint32_t size)
+{
+ nand_transfer_data_start(bank, direction, buffer, size);
+ uint32_t rc = nand_transfer_data_collect(direction);
+ return rc;
+}
+
+void ecc_start(uint32_t size, void* databuffer, void* sparebuffer, uint32_t type)
{
mutex_lock(&ecc_mtx);
- long timeout = current_tick + HZ / 50;
ECC_INT_CLR = 1;
SRCPND = INTMSK_ECC;
ECC_UNK1 = size;
ECC_DATA_PTR = (uint32_t)databuffer;
ECC_SPARE_PTR = (uint32_t)sparebuffer;
clean_dcache();
- ECC_CTRL = ECCCTRL_STARTDECODING;
+ ECC_CTRL = type;
+}
+
+uint32_t ecc_collect(void)
+{
+ long timeout = current_tick + HZ / 50;
while (!(SRCPND & INTMSK_ECC))
if (nand_timeout(timeout)) return ecc_unlock(1);
invalidate_dcache();
@@ -260,23 +276,18 @@ uint32_t ecc_decode(uint32_t size, void* databuffer, void* sparebuffer)
return ecc_unlock(ECC_RESULT);
}
+uint32_t ecc_decode(uint32_t size, void* databuffer, void* sparebuffer)
+{
+ ecc_start(size, databuffer, sparebuffer, ECCCTRL_STARTDECODING);
+ uint32_t rc = ecc_collect();
+ return rc;
+}
+
uint32_t ecc_encode(uint32_t size, void* databuffer, void* sparebuffer)
{
- mutex_lock(&ecc_mtx);
- long timeout = current_tick + HZ / 50;
- ECC_INT_CLR = 1;
- SRCPND = INTMSK_ECC;
- ECC_UNK1 = size;
- ECC_DATA_PTR = (uint32_t)databuffer;
- ECC_SPARE_PTR = (uint32_t)sparebuffer;
- clean_dcache();
- ECC_CTRL = ECCCTRL_STARTENCODING;
- while (!(SRCPND & INTMSK_ECC))
- if (nand_timeout(timeout)) return ecc_unlock(1);
- invalidate_dcache();
- ECC_INT_CLR = 1;
- SRCPND = INTMSK_ECC;
- return ecc_unlock(0);
+ ecc_start(size, databuffer, sparebuffer, ECCCTRL_STARTENCODING);
+ ecc_collect();
+ return 0;
}
uint32_t nand_check_empty(uint8_t* buffer)