summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Diedrich <ranma+coreboot@tdiedrich.de>2010-06-29 21:49:20 +0000
committerTobias Diedrich <ranma+coreboot@tdiedrich.de>2010-06-29 21:49:20 +0000
commitf4a00174b50c209f2a23b7a73fe7cb544ef59d02 (patch)
treec141affa250177d85f15dad6c77d45d7ca977bf1
parentc162f93f6fd8675bcf8079344c519bef5f343b3a (diff)
downloadrockbox-f4a00174b50c209f2a23b7a73fe7cb544ef59d02.tar.gz
rockbox-f4a00174b50c209f2a23b7a73fe7cb544ef59d02.zip
sd-as3525.c: handle acmd retries correctly
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27187 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 40392b35b2..9bfb2a9412 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -45,6 +45,8 @@
45#include "ata_idle_notify.h" 45#include "ata_idle_notify.h"
46#include "sd.h" 46#include "sd.h"
47#include "usb.h" 47#include "usb.h"
48/*#define LOGF_ENABLE*/
49#include "logf.h"
48 50
49#ifdef HAVE_HOTSWAP 51#ifdef HAVE_HOTSWAP
50#include "disk.h" 52#include "disk.h"
@@ -56,6 +58,8 @@
56#define MCI_NO_RESP (0<<0) 58#define MCI_NO_RESP (0<<0)
57#define MCI_RESP (1<<0) 59#define MCI_RESP (1<<0)
58#define MCI_LONG_RESP (1<<1) 60#define MCI_LONG_RESP (1<<1)
61#define MCI_ACMD (1<<2)
62#define MCI_NOCRC (1<<3)
59 63
60/* ARM PL180 registers */ 64/* ARM PL180 registers */
61#define MCI_POWER(i) (*(volatile unsigned char *) (pl180_base[i]+0x00)) 65#define MCI_POWER(i) (*(volatile unsigned char *) (pl180_base[i]+0x00))
@@ -210,6 +214,10 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
210 unsigned cmd_retries = 6; 214 unsigned cmd_retries = 6;
211 while(cmd_retries--) 215 while(cmd_retries--)
212 { 216 {
217 if ((flags & MCI_ACMD) && /* send SD_APP_CMD before each try */
218 !send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_RESP, response))
219 return false;
220
213 /* Clear old status flags */ 221 /* Clear old status flags */
214 MCI_CLEAR(drive) = 0x7ff; 222 MCI_CLEAR(drive) = 0x7ff;
215 223
@@ -236,8 +244,21 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
236 { 244 {
237 response[0] = MCI_RESP0(drive); /* Always prepare short response */ 245 response[0] = MCI_RESP0(drive); /* Always prepare short response */
238 246
239 if(status & MCI_RESPONSE_ERROR) /* timeout or crc failure */ 247 if(status & MCI_RESPONSE_ERROR) {/* timeout or crc failure */
248 if ((status & MCI_CMD_CRC_FAIL) &&
249 (flags & MCI_NOCRC))
250 break;
251 logf("sd cmd error: drive %d cmd %d arg %08x sd_status %08x resp0 %08lx",
252 drive, cmd, arg, status, response[0]);
240 continue; 253 continue;
254 }
255
256 if((flags & MCI_RESP) &&
257 !(flags & MCI_LONG_RESP) &&
258 (response[0] & SD_R1_CARD_ERROR)) {
259 logf("sd card error: drive %d cmd %d arg %08x r1 %08lx",
260 drive, cmd, arg, response[0]);
261 }
241 262
242 if(status & MCI_CMD_RESP_END) /* Response passed CRC check */ 263 if(status & MCI_CMD_RESP_END) /* Response passed CRC check */
243 { 264 {
@@ -268,6 +289,8 @@ static int sd_init_card(const int drive)
268 long init_timeout; 289 long init_timeout;
269 bool sd_v2 = false; 290 bool sd_v2 = false;
270 291
292 card_info[drive].rca = 0;
293
271 /* MCLCK on and set to 400kHz ident frequency */ 294 /* MCLCK on and set to 400kHz ident frequency */
272 MCI_CLOCK(drive) = MCI_IDENTSPEED; 295 MCI_CLOCK(drive) = MCI_IDENTSPEED;
273 296
@@ -293,12 +316,9 @@ static int sd_init_card(const int drive)
293 if(TIME_AFTER(current_tick, init_timeout)) 316 if(TIME_AFTER(current_tick, init_timeout))
294 return -2; 317 return -2;
295 318
296 /* app_cmd */
297 send_cmd(drive, SD_APP_CMD, 0, MCI_RESP, &response);
298
299 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ 319 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
300 send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), 320 send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)),
301 MCI_RESP, &card_info[drive].ocr); 321 MCI_ACMD|MCI_NOCRC|MCI_RESP, &card_info[drive].ocr);
302 322
303 } while(!(card_info[drive].ocr & (1<<31))); 323 } while(!(card_info[drive].ocr & (1<<31)));
304 324
@@ -365,17 +385,11 @@ static int sd_init_card(const int drive)
365 /* Switch to to 4 bit widebus mode */ 385 /* Switch to to 4 bit widebus mode */
366 if(sd_wait_for_tran_state(drive) < 0) 386 if(sd_wait_for_tran_state(drive) < 0)
367 return -11; 387 return -11;
368 /* CMD55 */ /* Response is requested due to timing issue */
369 if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_RESP, &response))
370 return -14;
371 /* ACMD42 */ 388 /* ACMD42 */
372 if(!send_cmd(drive, SD_SET_CLR_CARD_DETECT, 0, MCI_RESP, &response)) 389 if(!send_cmd(drive, SD_SET_CLR_CARD_DETECT, 0, MCI_ACMD|MCI_RESP, &response))
373 return -15; 390 return -15;
374 /* CMD55 */ /* Response is requested due to timing issue */
375 if(!send_cmd(drive, SD_APP_CMD, card_info[drive].rca, MCI_RESP, &response))
376 return -12;
377 /* ACMD6 */ 391 /* ACMD6 */
378 if(!send_cmd(drive, SD_SET_BUS_WIDTH, 2, MCI_RESP, &response)) 392 if(!send_cmd(drive, SD_SET_BUS_WIDTH, 2, MCI_ACMD|MCI_RESP, &response))
379 return -13; 393 return -13;
380 /* Now that card is widebus make controller aware */ 394 /* Now that card is widebus make controller aware */
381 MCI_CLOCK(drive) |= MCI_CLOCK_WIDEBUS; 395 MCI_CLOCK(drive) |= MCI_CLOCK_WIDEBUS;