diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/imx233/sdmmc-imx233.c | 59 |
1 files changed, 25 insertions, 34 deletions
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c index 164bf79eee..0d078229a8 100644 --- a/firmware/target/arm/imx233/sdmmc-imx233.c +++ b/firmware/target/arm/imx233/sdmmc-imx233.c | |||
@@ -316,7 +316,7 @@ static int init_sd_card(int drive) | |||
316 | imx233_ssp_set_block_size(ssp, 9); | 316 | imx233_ssp_set_block_size(ssp, 9); |
317 | 317 | ||
318 | SDMMC_RCA(drive) = 0; | 318 | SDMMC_RCA(drive) = 0; |
319 | bool sd_v2 = false; | 319 | bool sd_v2 = false, sd_hs = false; |
320 | uint32_t resp; | 320 | uint32_t resp; |
321 | long init_timeout; | 321 | long init_timeout; |
322 | /* go to idle state */ | 322 | /* go to idle state */ |
@@ -349,35 +349,6 @@ static int init_sd_card(int drive) | |||
349 | if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &SDMMC_INFO(drive).rca)) | 349 | if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &SDMMC_INFO(drive).rca)) |
350 | return -4; | 350 | return -4; |
351 | 351 | ||
352 | /* Try to switch V2 cards to HS timings, non HS seem to ignore this */ | ||
353 | if(sd_v2) | ||
354 | { | ||
355 | /* CMD7 w/rca: Select card to put it in TRAN state */ | ||
356 | if(!send_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_RESP, NULL)) | ||
357 | return -5; | ||
358 | |||
359 | if(wait_for_state(drive, SD_TRAN)) | ||
360 | return -6; | ||
361 | |||
362 | /* CMD6 */ | ||
363 | { | ||
364 | /* only transfer 64 bytes */ | ||
365 | imx233_ssp_set_block_size(ssp, /*log2(64)*/6); | ||
366 | if(imx233_ssp_sd_mmc_transfer(ssp, SD_SWITCH_FUNC, 0x80fffff1, | ||
367 | SSP_SHORT_RESP, aligned_buffer[drive], 1, true, true, NULL)) | ||
368 | { | ||
369 | imx233_ssp_set_block_size(ssp, /*log2(512)*/9); | ||
370 | return -12; | ||
371 | } | ||
372 | imx233_ssp_set_block_size(ssp, /*log2(512)*/9); | ||
373 | } | ||
374 | |||
375 | /* go back to STBY state so we can read csd */ | ||
376 | /* CMD7 w/rca=0: Deselect card to put it in STBY state */ | ||
377 | if(!send_cmd(drive, SD_DESELECT_CARD, 0, MCI_NO_RESP, NULL)) | ||
378 | return -8; | ||
379 | } | ||
380 | |||
381 | /* CMD9 send CSD */ | 352 | /* CMD9 send CSD */ |
382 | if(!send_cmd(drive, SD_SEND_CSD, SDMMC_RCA(drive), MCI_RESP|MCI_LONG_RESP, | 353 | if(!send_cmd(drive, SD_SEND_CSD, SDMMC_RCA(drive), MCI_RESP|MCI_LONG_RESP, |
383 | SDMMC_INFO(drive).csd)) | 354 | SDMMC_INFO(drive).csd)) |
@@ -387,10 +358,6 @@ static int init_sd_card(int drive) | |||
387 | window_start[drive] = 0; | 358 | window_start[drive] = 0; |
388 | window_end[drive] = SDMMC_INFO(drive).numblocks; | 359 | window_end[drive] = SDMMC_INFO(drive).numblocks; |
389 | 360 | ||
390 | /* SSPCLK @ 96MHz | ||
391 | * gives bitrate of 96 / 4 / 1 = 24MHz */ | ||
392 | imx233_ssp_set_timings(ssp, 4, 0, 0xffff); | ||
393 | |||
394 | /* CMD7 w/rca: Select card to put it in TRAN state */ | 361 | /* CMD7 w/rca: Select card to put it in TRAN state */ |
395 | if(!send_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_RESP, &resp)) | 362 | if(!send_cmd(drive, SD_SELECT_CARD, SDMMC_RCA(drive), MCI_RESP, &resp)) |
396 | return -12; | 363 | return -12; |
@@ -407,6 +374,22 @@ static int init_sd_card(int drive) | |||
407 | /* Switch to 4-bit */ | 374 | /* Switch to 4-bit */ |
408 | imx233_ssp_set_bus_width(ssp, 4); | 375 | imx233_ssp_set_bus_width(ssp, 4); |
409 | 376 | ||
377 | /* Try to switch V2 cards to HS timings, non HS seem to ignore this */ | ||
378 | if(sd_v2) | ||
379 | { | ||
380 | /* CMD6 switch to HS */ | ||
381 | { | ||
382 | /* only transfer 64 bytes */ | ||
383 | imx233_ssp_set_block_size(ssp, /*log2(64)*/6); | ||
384 | if(imx233_ssp_sd_mmc_transfer(ssp, SD_SWITCH_FUNC, 0x80fffff1, | ||
385 | SSP_SHORT_RESP, aligned_buffer[drive], 1, true, true, NULL)) | ||
386 | return -12; | ||
387 | imx233_ssp_set_block_size(ssp, /*log2(512)*/9); | ||
388 | if((aligned_buffer[drive][16] & 0xf) == 1) | ||
389 | sd_hs = true; | ||
390 | } | ||
391 | } | ||
392 | |||
410 | /* probe for CMD23 support */ | 393 | /* probe for CMD23 support */ |
411 | support_set_block_count[drive] = false; | 394 | support_set_block_count[drive] = false; |
412 | /* ACMD51, only transfer 8 bytes */ | 395 | /* ACMD51, only transfer 8 bytes */ |
@@ -422,6 +405,14 @@ static int init_sd_card(int drive) | |||
422 | } | 405 | } |
423 | imx233_ssp_set_block_size(ssp, /*log2(512)*/9); | 406 | imx233_ssp_set_block_size(ssp, /*log2(512)*/9); |
424 | 407 | ||
408 | /* SSPCLK @ 96MHz | ||
409 | * gives bitrate of 96 / 4 / 1 = 24MHz | ||
410 | * gives bitrate of 96 / 2 / 1 = 48MHz */ | ||
411 | if(sd_hs) | ||
412 | imx233_ssp_set_timings(ssp, 2, 0, 0xffff); | ||
413 | else | ||
414 | imx233_ssp_set_timings(ssp, 4, 0, 0xffff); | ||
415 | |||
425 | SDMMC_INFO(drive).initialized = 1; | 416 | SDMMC_INFO(drive).initialized = 1; |
426 | 417 | ||
427 | return 0; | 418 | return 0; |