1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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}
|