diff options
-rw-r--r-- | firmware/target/arm/imx233/sdmmc-imx233.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c index 9aafb5820a..5ebf0c7d3b 100644 --- a/firmware/target/arm/imx233/sdmmc-imx233.c +++ b/firmware/target/arm/imx233/sdmmc-imx233.c | |||
@@ -148,6 +148,7 @@ static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR; | |||
148 | static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES]; | 148 | static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES]; |
149 | static struct mutex mutex[SDMMC_NUM_DRIVES]; | 149 | static struct mutex mutex[SDMMC_NUM_DRIVES]; |
150 | static int disk_last_activity[SDMMC_NUM_DRIVES]; | 150 | static int disk_last_activity[SDMMC_NUM_DRIVES]; |
151 | static bool support_set_block_count[SDMMC_NUM_DRIVES]; | ||
151 | #define MIN_YIELD_PERIOD 5 | 152 | #define MIN_YIELD_PERIOD 5 |
152 | 153 | ||
153 | #define SDMMC_INFO(drive) sdmmc_card_info[drive] | 154 | #define SDMMC_INFO(drive) sdmmc_card_info[drive] |
@@ -400,6 +401,21 @@ static int init_sd_card(int drive) | |||
400 | /* Switch to 4-bit */ | 401 | /* Switch to 4-bit */ |
401 | imx233_ssp_set_bus_width(ssp, 4); | 402 | imx233_ssp_set_bus_width(ssp, 4); |
402 | 403 | ||
404 | /* probe for CMD23 support */ | ||
405 | support_set_block_count[drive] = false; | ||
406 | /* ACMD51, only transfer 8 bytes */ | ||
407 | imx233_ssp_set_block_size(ssp, /*log2(8)*/3); | ||
408 | if(send_cmd(drive, SD_APP_CMD, SDMMC_RCA(drive), MCI_RESP, &resp)) | ||
409 | { | ||
410 | if(imx233_ssp_sd_mmc_transfer(ssp, SD_SEND_SCR, 0, SSP_SHORT_RESP, | ||
411 | aligned_buffer[drive], 1, true, true, NULL) == SSP_SUCCESS) | ||
412 | { | ||
413 | if(aligned_buffer[drive][3] & 2) | ||
414 | support_set_block_count[drive] = true; | ||
415 | } | ||
416 | } | ||
417 | imx233_ssp_set_block_size(ssp, /*log2(512)*/9); | ||
418 | |||
403 | SDMMC_INFO(drive).initialized = 1; | 419 | SDMMC_INFO(drive).initialized = 1; |
404 | 420 | ||
405 | return 0; | 421 | return 0; |
@@ -485,6 +501,10 @@ static int init_mmc_drive(int drive) | |||
485 | if(!send_cmd(drive, MMC_DESELECT_CARD, 0, MCI_NO_RESP, NULL)) | 501 | if(!send_cmd(drive, MMC_DESELECT_CARD, 0, MCI_NO_RESP, NULL)) |
486 | return -13; | 502 | return -13; |
487 | 503 | ||
504 | /* MMC always support CMD23 */ | ||
505 | support_set_block_count[drive] = false; | ||
506 | SDMMC_INFO(drive).initialized = 1; | ||
507 | |||
488 | return 0; | 508 | return 0; |
489 | } | 509 | } |
490 | #endif | 510 | #endif |
@@ -497,6 +517,9 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, | |||
497 | while(count != 0) | 517 | while(count != 0) |
498 | { | 518 | { |
499 | int this_count = MIN(count, IMX233_MAX_SINGLE_DMA_XFER_SIZE / 512); | 519 | int this_count = MIN(count, IMX233_MAX_SINGLE_DMA_XFER_SIZE / 512); |
520 | bool need_stop = true; | ||
521 | if(support_set_block_count[drive] && send_cmd(drive, 23, this_count, MCI_RESP, &resp)) | ||
522 | need_stop = false; | ||
500 | /* Set bank_start to the correct unit (blocks or bytes). | 523 | /* Set bank_start to the correct unit (blocks or bytes). |
501 | * MMC drives use block addressing, SD cards bytes or blocks */ | 524 | * MMC drives use block addressing, SD cards bytes or blocks */ |
502 | int bank_start = start; | 525 | int bank_start = start; |
@@ -508,14 +531,16 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, | |||
508 | read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK, | 531 | read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK, |
509 | bank_start, SSP_SHORT_RESP, buf, this_count, false, read, &resp); | 532 | bank_start, SSP_SHORT_RESP, buf, this_count, false, read, &resp); |
510 | if(ret != SSP_SUCCESS) | 533 | if(ret != SSP_SUCCESS) |
511 | break; | 534 | need_stop = true; |
512 | /* stop transmission | 535 | /* stop transmission |
513 | * NOTE: rely on SD_STOP_TRANSMISSION=MMC_STOP_TRANSMISSION */ | 536 | * NOTE: rely on SD_STOP_TRANSMISSION=MMC_STOP_TRANSMISSION */ |
514 | if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP|MCI_BUSY, &resp)) | 537 | if(need_stop && !send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP|MCI_BUSY, &resp)) |
515 | { | 538 | { |
516 | ret = -15; | 539 | ret = -15; |
517 | break; | 540 | break; |
518 | } | 541 | } |
542 | if(ret != 0) | ||
543 | return ret; | ||
519 | count -= this_count; | 544 | count -= this_count; |
520 | start += this_count; | 545 | start += this_count; |
521 | buf += this_count * 512; | 546 | buf += this_count * 512; |