2 * Milkymist SoC (Software)
3 * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <hw/memcard.h>
24 //#define MEMCARD_DEBUG
26 static void memcard_start_cmd_tx(void)
28 CSR_MEMCARD_ENABLE
= MEMCARD_ENABLE_CMD_TX
;
31 static void memcard_start_cmd_rx(void)
33 CSR_MEMCARD_PENDING
= MEMCARD_PENDING_CMD_RX
;
34 CSR_MEMCARD_START
= MEMCARD_START_CMD_RX
;
35 CSR_MEMCARD_ENABLE
= MEMCARD_ENABLE_CMD_RX
;
38 static void memcard_start_cmd_dat_rx(void)
40 CSR_MEMCARD_PENDING
= MEMCARD_PENDING_CMD_RX
|MEMCARD_PENDING_DAT_RX
;
41 CSR_MEMCARD_START
= MEMCARD_START_CMD_RX
|MEMCARD_START_DAT_RX
;
42 CSR_MEMCARD_ENABLE
= MEMCARD_ENABLE_CMD_RX
|MEMCARD_ENABLE_DAT_RX
;
45 static void memcard_send_command(unsigned char cmd
, unsigned int arg
)
47 unsigned char packet
[6];
53 packet
[0] = cmd
| 0x40;
54 packet
[1] = ((arg
>> 24) & 0xff);
55 packet
[2] = ((arg
>> 16) & 0xff);
56 packet
[3] = ((arg
>> 8) & 0xff);
57 packet
[4] = (arg
& 0xff);
64 if((data
& 0x80) ^ (crc
& 0x80))
74 printf(">> %02x %02x %02x %02x %02x %02x\n", packet
[0], packet
[1], packet
[2], packet
[3], packet
[4], packet
[5]);
78 CSR_MEMCARD_CMD
= packet
[i
];
79 while(CSR_MEMCARD_PENDING
& MEMCARD_PENDING_CMD_TX
);
83 static void memcard_send_dummy(void)
85 CSR_MEMCARD_CMD
= 0xff;
86 while(CSR_MEMCARD_PENDING
& MEMCARD_PENDING_CMD_TX
);
89 static int memcard_receive_command(unsigned char *buffer
, int len
)
96 while(!(CSR_MEMCARD_PENDING
& MEMCARD_PENDING_CMD_RX
)) {
100 printf("Command receive timeout\n");
105 buffer
[i
] = CSR_MEMCARD_CMD
;
106 CSR_MEMCARD_PENDING
= MEMCARD_PENDING_CMD_RX
;
109 while(!(CSR_MEMCARD_PENDING
& MEMCARD_PENDING_CMD_RX
));
114 printf("%02x ", buffer
[i
]);
121 static int memcard_receive_command_data(unsigned char *command
, unsigned int *data
)
130 while(!(CSR_MEMCARD_PENDING
& (MEMCARD_PENDING_CMD_RX
|MEMCARD_PENDING_DAT_RX
))) {
134 printf("Command receive timeout\n");
139 if(CSR_MEMCARD_PENDING
& MEMCARD_PENDING_CMD_RX
) {
140 command
[i
++] = CSR_MEMCARD_CMD
;
141 CSR_MEMCARD_PENDING
= MEMCARD_PENDING_CMD_RX
;
143 CSR_MEMCARD_ENABLE
= MEMCARD_ENABLE_DAT_RX
; /* disable command RX */
145 if(CSR_MEMCARD_PENDING
& MEMCARD_PENDING_DAT_RX
) {
146 data
[j
++] = CSR_MEMCARD_DAT
;
147 CSR_MEMCARD_PENDING
= MEMCARD_PENDING_DAT_RX
;
151 /* Get CRC (ignored) */
153 while(!(CSR_MEMCARD_PENDING
& MEMCARD_PENDING_DAT_RX
));
155 printf("CRC: %08x\n", CSR_MEMCARD_DAT
);
157 CSR_MEMCARD_PENDING
= MEMCARD_PENDING_DAT_RX
;
160 while(!(CSR_MEMCARD_PENDING
& MEMCARD_PENDING_DAT_RX
));
163 printf("<< %02x %02x %02x %02x %02x %02x\n", command
[0], command
[1], command
[2], command
[3], command
[4], command
[5]);
167 // printf("%08x ", data[i]);
173 static int memcard_init(void)
178 CSR_MEMCARD_CLK2XDIV
= 250;
181 memcard_start_cmd_tx();
182 memcard_send_command(0, 0);
184 memcard_send_dummy();
187 memcard_send_command(8, 0x1aa);
188 memcard_start_cmd_rx();
189 if(!memcard_receive_command(b
, 6)) return 0;
191 /* ACMD41 - initialize */
193 memcard_start_cmd_tx();
194 memcard_send_command(55, 0);
195 memcard_start_cmd_rx();
196 if(!memcard_receive_command(b
, 6)) return 0;
197 memcard_start_cmd_tx();
198 memcard_send_command(41, 0x00300000);
199 memcard_start_cmd_rx();
200 if(!memcard_receive_command(b
, 6)) return 0;
201 if(b
[1] & 0x80) break;
203 printf("Card is busy, retrying\n");
208 memcard_start_cmd_tx();
209 memcard_send_command(2, 0);
210 memcard_start_cmd_rx();
211 if(!memcard_receive_command(b
, 17)) return 0;
214 memcard_start_cmd_tx();
215 memcard_send_command(3, 0);
216 memcard_start_cmd_rx();
217 if(!memcard_receive_command(b
, 6)) return 0;
218 rca
= (((unsigned int)b
[1]) << 8)|((unsigned int)b
[2]);
220 printf("RCA: %04x\n", rca
);
223 /* CMD7 - select card */
224 memcard_start_cmd_tx();
225 memcard_send_command(7, rca
<< 16);
226 memcard_start_cmd_rx();
227 if(!memcard_receive_command(b
, 6)) return 0;
229 /* ACMD6 - set bus width */
230 memcard_start_cmd_tx();
231 memcard_send_command(55, rca
<< 16);
232 memcard_start_cmd_rx();
233 if(!memcard_receive_command(b
, 6)) return 0;
234 memcard_start_cmd_tx();
235 memcard_send_command(6, 2);
236 memcard_start_cmd_rx();
237 if(!memcard_receive_command(b
, 6)) return 0;
239 CSR_MEMCARD_CLK2XDIV
= 3;
244 static int memcard_readblock(unsigned int block
, void *buffer
)
248 /* CMD17 - read block */
249 memcard_start_cmd_tx();
250 memcard_send_command(17, block
*512);
251 memcard_start_cmd_dat_rx();
252 if(!memcard_receive_command_data(b
, (unsigned int *)buffer
)) return 0;
256 int bd_init(int devnr
)
258 return memcard_init();
261 int bd_readblock(unsigned int block
, void *buffer
)
263 return memcard_readblock(block
, buffer
);
270 int bd_has_part_table(int devnr
)