diff options
Diffstat (limited to 'firmware/target/arm/as3525/ata_sd_as3525.c')
-rw-r--r-- | firmware/target/arm/as3525/ata_sd_as3525.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/firmware/target/arm/as3525/ata_sd_as3525.c b/firmware/target/arm/as3525/ata_sd_as3525.c index ee4b8c015d..6a2860528f 100644 --- a/firmware/target/arm/as3525/ata_sd_as3525.c +++ b/firmware/target/arm/as3525/ata_sd_as3525.c | |||
@@ -246,12 +246,22 @@ static int sd_init_card(const int drive) | |||
246 | unsigned long temp_reg[4]; | 246 | unsigned long temp_reg[4]; |
247 | int i; | 247 | int i; |
248 | 248 | ||
249 | |||
250 | /* 100 - 400kHz clock required for Identification Mode */ | ||
251 | MCI_CLOCK(drive) = (MCI_CLOCK(drive) & 0xf00) | AS3525_SD_IDENT_DIV; | ||
252 | |||
253 | |||
254 | /* Start of Card Identification Mode ************************************/ | ||
255 | |||
256 | |||
257 | /* CMD0 Go Idle */ | ||
249 | if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_FLAGS, NULL)) | 258 | if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_FLAGS, NULL)) |
250 | return -1; | 259 | return -1; |
251 | 260 | ||
252 | mci_delay(); | 261 | mci_delay(); |
253 | 262 | ||
254 | /* CMD8 Check for v2 sd card */ | 263 | /* CMD8 Check for v2 sd card. Must be sent before using ACMD41 |
264 | Non v2 cards will not respond to this command*/ | ||
255 | if(send_cmd(drive, SD_SEND_IF_COND, 0x1AA, MCI_RESP|MCI_ARG, &response)) | 265 | if(send_cmd(drive, SD_SEND_IF_COND, 0x1AA, MCI_RESP|MCI_ARG, &response)) |
256 | if((response & 0xFFF) == 0x1AA) | 266 | if((response & 0xFFF) == 0x1AA) |
257 | sd_v2 = true; | 267 | sd_v2 = true; |
@@ -270,7 +280,7 @@ static int sd_init_card(const int drive) | |||
270 | return -3; | 280 | return -3; |
271 | } | 281 | } |
272 | 282 | ||
273 | /* acmd41 If we have a v2 sd card set HCS bit[30] with voltage range */ | 283 | /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ |
274 | if(!send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), | 284 | if(!send_cmd(drive, SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)), |
275 | MCI_RESP|MCI_ARG, &card_info[drive].ocr)) | 285 | MCI_RESP|MCI_ARG, &card_info[drive].ocr)) |
276 | { | 286 | { |
@@ -279,10 +289,7 @@ static int sd_init_card(const int drive) | |||
279 | 289 | ||
280 | } while(!(card_info[drive].ocr & (1<<31))); | 290 | } while(!(card_info[drive].ocr & (1<<31))); |
281 | 291 | ||
282 | MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS; /* full speed for controller clock */ | 292 | /* CMD2 send CID */ |
283 | mci_delay(); | ||
284 | |||
285 | /* send CID */ | ||
286 | if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, | 293 | if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP|MCI_ARG, |
287 | temp_reg)) | 294 | temp_reg)) |
288 | return -5; | 295 | return -5; |
@@ -290,12 +297,20 @@ static int sd_init_card(const int drive) | |||
290 | for(i=0; i<4; i++) | 297 | for(i=0; i<4; i++) |
291 | card_info[drive].cid[3-i] = temp_reg[i]; | 298 | card_info[drive].cid[3-i] = temp_reg[i]; |
292 | 299 | ||
293 | /* send RCA */ | 300 | /* CMD3 send RCA */ |
294 | if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG, | 301 | if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP|MCI_ARG, |
295 | &card_info[drive].rca)) | 302 | &card_info[drive].rca)) |
296 | return -6; | 303 | return -6; |
297 | 304 | ||
298 | /* Select card to put it in TRAN state */ | 305 | |
306 | /* End of Card Identification Mode ************************************/ | ||
307 | |||
308 | |||
309 | /* full speed for controller clock MCICLK = MCLK = PCLK = 62 MHz */ | ||
310 | MCI_CLOCK(drive) |= MCI_CLOCK_BYPASS; /* FIXME: 50 MHz is spec limit */ | ||
311 | mci_delay(); | ||
312 | |||
313 | /* CMD7 w/rca: Select card to put it in TRAN state */ | ||
299 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) | 314 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) |
300 | return -7; | 315 | return -7; |
301 | 316 | ||
@@ -304,16 +319,18 @@ static int sd_init_card(const int drive) | |||
304 | { | 319 | { |
305 | if(sd_wait_for_state(drive, SD_TRAN)) | 320 | if(sd_wait_for_state(drive, SD_TRAN)) |
306 | return -8; | 321 | return -8; |
322 | /* CMD6 */ | ||
307 | if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_ARG, NULL)) | 323 | if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_ARG, NULL)) |
308 | return -9; | 324 | return -9; |
309 | mci_delay(); | 325 | mci_delay(); |
310 | } | 326 | } |
311 | 327 | ||
312 | /* go back to STBY state so we can read csd */ | 328 | /* go back to STBY state so we can read csd */ |
329 | /* CMD7 w/rca=0: Deselect card to put it in STBY state */ | ||
313 | if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_ARG, NULL)) | 330 | if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_ARG, NULL)) |
314 | return -10; | 331 | return -10; |
315 | 332 | ||
316 | /* send CSD */ | 333 | /* CMD9 send CSD */ |
317 | if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, | 334 | if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca, |
318 | MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) | 335 | MCI_RESP|MCI_LONG_RESP|MCI_ARG, temp_reg)) |
319 | return -11; | 336 | return -11; |
@@ -323,7 +340,7 @@ static int sd_init_card(const int drive) | |||
323 | 340 | ||
324 | sd_parse_csd(&card_info[drive]); | 341 | sd_parse_csd(&card_info[drive]); |
325 | 342 | ||
326 | /* Select card to put back in TRAN state */ | 343 | /* CMD7 w/rca: Select card to put it in TRAN state */ |
327 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) | 344 | if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_ARG, NULL)) |
328 | return -12; | 345 | return -12; |
329 | 346 | ||
@@ -440,8 +457,8 @@ static void init_pl180_controller(const int drive) | |||
440 | MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0; | 457 | MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0; |
441 | MCI_CLEAR(drive) = 0x7ff; | 458 | MCI_CLEAR(drive) = 0x7ff; |
442 | 459 | ||
443 | MCI_MASK0(drive) = MCI_MASK1(drive) = MCI_ERROR | MCI_DATA_END; | 460 | MCI_MASK0(drive) = MCI_ERROR | MCI_DATA_END; |
444 | 461 | MCI_MASK1(drive) = 0; | |
445 | #ifdef HAVE_MULTIDRIVE | 462 | #ifdef HAVE_MULTIDRIVE |
446 | VIC_INT_ENABLE |= | 463 | VIC_INT_ENABLE |= |
447 | (drive == INTERNAL_AS3525) ? INTERRUPT_NAND : INTERRUPT_MCI0; | 464 | (drive == INTERNAL_AS3525) ? INTERRUPT_NAND : INTERRUPT_MCI0; |
@@ -459,7 +476,7 @@ static void init_pl180_controller(const int drive) | |||
459 | VIC_INT_ENABLE |= INTERRUPT_NAND; | 476 | VIC_INT_ENABLE |= INTERRUPT_NAND; |
460 | #endif | 477 | #endif |
461 | 478 | ||
462 | MCI_POWER(drive) = MCI_POWER_UP|(10 /*voltage*/ << 2); /* use OF voltage */ | 479 | MCI_POWER(drive) = MCI_POWER_UP | (MCI_VDD_3_0); /* OF Setting */ |
463 | mci_delay(); | 480 | mci_delay(); |
464 | 481 | ||
465 | MCI_POWER(drive) |= MCI_POWER_ON; | 482 | MCI_POWER(drive) |= MCI_POWER_ON; |
@@ -467,7 +484,7 @@ static void init_pl180_controller(const int drive) | |||
467 | 484 | ||
468 | MCI_SELECT(drive) = 0; | 485 | MCI_SELECT(drive) = 0; |
469 | 486 | ||
470 | MCI_CLOCK(drive) = MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV; | 487 | MCI_CLOCK(drive) = MCI_CLOCK_ENABLE; |
471 | mci_delay(); | 488 | mci_delay(); |
472 | } | 489 | } |
473 | 490 | ||