diff options
Diffstat (limited to 'board/st/u8500/mmc_fifo.S')
-rw-r--r-- | board/st/u8500/mmc_fifo.S | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/board/st/u8500/mmc_fifo.S b/board/st/u8500/mmc_fifo.S new file mode 100644 index 000000000..44911a8d5 --- /dev/null +++ b/board/st/u8500/mmc_fifo.S @@ -0,0 +1,146 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com> + * + * License terms: GNU General Public License (GPL), version 2. + */ + +#include "mmc_fifo.h" +#include "mmc_host.h" + +/* + * Function: mmc_fifo_read() + * + * int mmc_fifo_read(u32 *fifo, u32 *buf, unsigned int count, u32 *status_reg) + * + * Info: Reads data from an MMC (ARM PL180) FIFO + * + * Parameters: + * fifo - pointer to the first PL180 FIFO register + * buf - pointer to a read buffer (32-bit aligned) + * count - number of bytes to be read (32-bit aligned) + * status_reg - pointer to the PL180 status register + * + * Returns '0' if success and PL180 status on failure. + * + */ + + .globl mmc_fifo_read +mmc_fifo_read: + push {r4-r10,lr} +mmc_fifo_read_loop_32_1: + /* If count is <32B read word-wise */ + cmp r2,#32 + blo mmc_fifo_read_loop_4_1 +mmc_fifo_read_loop_32_2: + /* Load SDI_STA to r4 */ + ldr r4,[r3] + /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */ + ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT) + bne mmc_fifo_read_fail + /* Wait until SDI_STA_RXFIFOBR is set */ + tst r4,#SDI_STA_RXFIFOBR + beq mmc_fifo_read_loop_32_2 + /* Load and store 8 words */ + ldmia r0,{r4-r10,lr} + stmia r1!,{r4-r10,lr} + subs r2,r2,#32 + b mmc_fifo_read_loop_32_1 +mmc_fifo_read_loop_4_1: + /* Read word wise */ + cmp r2,#4 + blo mmc_fifo_read_ok +mmc_fifo_read_loop_4_2: + /* Load SDI_STA to r4 */ + ldr r4,[r3] + /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */ + ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT) + bne mmc_fifo_read_fail + /* Wait until SDI_STA_RXDAVL is set */ + tst r4,#SDI_STA_RXDAVL + beq mmc_fifo_read_loop_4_2 + /* Load and store 1 word */ + ldmia r0,{r4} + stmia r1!,{r4} + subs r2,r2,#4 + b mmc_fifo_read_loop_4_1 +mmc_fifo_read_ok: + /* Wait until SDI_STA_DBCKEND and SDI_STA_DATAEND are set */ + ldr r4,[r3] + ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT) + bne mmc_fifo_read_fail + and r5,r4,#(SDI_STA_DBCKEND | SDI_STA_DATAEND) + cmp r5,#(SDI_STA_DBCKEND | SDI_STA_DATAEND) + bne mmc_fifo_read_ok +mmc_fifo_read_fail: + mov r0,r4 + pop {r4-r10,pc} + +/* + * Function: mmc_fifo_write() + * + * int mmc_fifo_write(u32 *buf, u32 *fifo, unsigned int count, u32 *status_reg) + * + * Info: Writes data to an MMC (ARM PL180) FIFO + * + * Parameters: + * buf - pointer to a write buffer (32-bit aligned) + * fifo - pointer to the first PL180 FIFO register + * count - number of bytes to be written (32-bit aligned) + * status_reg - pointer to the PL180 status register + * + * Returns '0' if success and PL180 status on failure. + * + */ + + .globl mmc_fifo_write +mmc_fifo_write: + push {r4-r10,lr} +mmc_fifo_write_loop_32_1: + /* If count is <32B read word-wise */ + cmp r2,#32 + blo mmc_fifo_write_loop_4_1 +mmc_fifo_write_loop_32_2: + /* Load SDI_STA to r4 */ + ldr r4,[r3] + /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */ + ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT) + bne mmc_fifo_write_fail + /* Wait until SDI_STA_TXFIFOBW is set */ + tst r4,#SDI_STA_TXFIFOBW + beq mmc_fifo_write_loop_32_2 + /* Load and store 8 words */ + ldmia r0!,{r4-r10,lr} + stmia r1,{r4-r10,lr} + subs r2,r2,#32 + b mmc_fifo_write_loop_32_1 +mmc_fifo_write_loop_4_1: + /* Read word wise */ + cmp r2,#4 + blo mmc_fifo_write_ok +mmc_fifo_write_loop_4_2: + /* Load SDI_STA to r4 */ + ldr r4,[r3] + /* Exit if SDI_STA_DCRCFAIL or SDI_STA_DTIMEOUT is set */ + ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT) + bne mmc_fifo_write_fail + /* Wait until SDI_STA_TXFIFOBW is set */ + tst r4,#SDI_STA_TXFIFOBW + beq mmc_fifo_write_loop_4_2 + /* Load and store 1 word */ + ldmia r0!,{r4} + stmia r1,{r4} + subs r2,r2,#4 + b mmc_fifo_write_loop_4_1 +mmc_fifo_write_ok: + /* Wait until SDI_STA_DBCKEND and SDI_STA_DATAEND are set */ + ldr r4,[r3] + ands r5,r4,#(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT) + bne mmc_fifo_write_fail + and r5,r4,#(SDI_STA_DBCKEND | SDI_STA_DATAEND) + cmp r5,#(SDI_STA_DBCKEND | SDI_STA_DATAEND) + bne mmc_fifo_write_ok +mmc_fifo_write_fail: + mov r0,r4 + pop {r4-r10,pc} |