forked from len0rd/rockbox
imx233: add support for CMD23 in sd/mmc
This allows tells the card the number of blocks that will be transfered. This is usually faster than continuous read/write. It is mandatory for MMC and on SD cards, support is probed. Change-Id: Ide3f97c26c2b714390884c69e05b00c2caa552f8
This commit is contained in:
parent
9a58721974
commit
e90a5efe54
1 changed files with 27 additions and 2 deletions
|
|
@ -148,6 +148,7 @@ static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR;
|
||||||
static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
|
static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
|
||||||
static struct mutex mutex[SDMMC_NUM_DRIVES];
|
static struct mutex mutex[SDMMC_NUM_DRIVES];
|
||||||
static int disk_last_activity[SDMMC_NUM_DRIVES];
|
static int disk_last_activity[SDMMC_NUM_DRIVES];
|
||||||
|
static bool support_set_block_count[SDMMC_NUM_DRIVES];
|
||||||
#define MIN_YIELD_PERIOD 5
|
#define MIN_YIELD_PERIOD 5
|
||||||
|
|
||||||
#define SDMMC_INFO(drive) sdmmc_card_info[drive]
|
#define SDMMC_INFO(drive) sdmmc_card_info[drive]
|
||||||
|
|
@ -400,6 +401,21 @@ static int init_sd_card(int drive)
|
||||||
/* Switch to 4-bit */
|
/* Switch to 4-bit */
|
||||||
imx233_ssp_set_bus_width(ssp, 4);
|
imx233_ssp_set_bus_width(ssp, 4);
|
||||||
|
|
||||||
|
/* probe for CMD23 support */
|
||||||
|
support_set_block_count[drive] = false;
|
||||||
|
/* ACMD51, only transfer 8 bytes */
|
||||||
|
imx233_ssp_set_block_size(ssp, /*log2(8)*/3);
|
||||||
|
if(send_cmd(drive, SD_APP_CMD, SDMMC_RCA(drive), MCI_RESP, &resp))
|
||||||
|
{
|
||||||
|
if(imx233_ssp_sd_mmc_transfer(ssp, SD_SEND_SCR, 0, SSP_SHORT_RESP,
|
||||||
|
aligned_buffer[drive], 1, true, true, NULL) == SSP_SUCCESS)
|
||||||
|
{
|
||||||
|
if(aligned_buffer[drive][3] & 2)
|
||||||
|
support_set_block_count[drive] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imx233_ssp_set_block_size(ssp, /*log2(512)*/9);
|
||||||
|
|
||||||
SDMMC_INFO(drive).initialized = 1;
|
SDMMC_INFO(drive).initialized = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -485,6 +501,10 @@ static int init_mmc_drive(int drive)
|
||||||
if(!send_cmd(drive, MMC_DESELECT_CARD, 0, MCI_NO_RESP, NULL))
|
if(!send_cmd(drive, MMC_DESELECT_CARD, 0, MCI_NO_RESP, NULL))
|
||||||
return -13;
|
return -13;
|
||||||
|
|
||||||
|
/* MMC always support CMD23 */
|
||||||
|
support_set_block_count[drive] = false;
|
||||||
|
SDMMC_INFO(drive).initialized = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -497,6 +517,9 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
|
||||||
while(count != 0)
|
while(count != 0)
|
||||||
{
|
{
|
||||||
int this_count = MIN(count, IMX233_MAX_SINGLE_DMA_XFER_SIZE / 512);
|
int this_count = MIN(count, IMX233_MAX_SINGLE_DMA_XFER_SIZE / 512);
|
||||||
|
bool need_stop = true;
|
||||||
|
if(support_set_block_count[drive] && send_cmd(drive, 23, this_count, MCI_RESP, &resp))
|
||||||
|
need_stop = false;
|
||||||
/* Set bank_start to the correct unit (blocks or bytes).
|
/* Set bank_start to the correct unit (blocks or bytes).
|
||||||
* MMC drives use block addressing, SD cards bytes or blocks */
|
* MMC drives use block addressing, SD cards bytes or blocks */
|
||||||
int bank_start = start;
|
int bank_start = start;
|
||||||
|
|
@ -508,14 +531,16 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
|
||||||
read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK,
|
read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK,
|
||||||
bank_start, SSP_SHORT_RESP, buf, this_count, false, read, &resp);
|
bank_start, SSP_SHORT_RESP, buf, this_count, false, read, &resp);
|
||||||
if(ret != SSP_SUCCESS)
|
if(ret != SSP_SUCCESS)
|
||||||
break;
|
need_stop = true;
|
||||||
/* stop transmission
|
/* stop transmission
|
||||||
* NOTE: rely on SD_STOP_TRANSMISSION=MMC_STOP_TRANSMISSION */
|
* NOTE: rely on SD_STOP_TRANSMISSION=MMC_STOP_TRANSMISSION */
|
||||||
if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP|MCI_BUSY, &resp))
|
if(need_stop && !send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP|MCI_BUSY, &resp))
|
||||||
{
|
{
|
||||||
ret = -15;
|
ret = -15;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(ret != 0)
|
||||||
|
return ret;
|
||||||
count -= this_count;
|
count -= this_count;
|
||||||
start += this_count;
|
start += this_count;
|
||||||
buf += this_count * 512;
|
buf += this_count * 512;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue