mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 11:21:23 +00:00
sdmmc: Add support for SDSC cards
This commit is contained in:
parent
6e314933d9
commit
a4a056128a
1 changed files with 24 additions and 19 deletions
|
@ -145,6 +145,10 @@ static int _sdmmc_storage_readwrite_ex(sdmmc_storage_t *storage, u32 *blkcnt_out
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
sdmmc_req_t reqbuf;
|
sdmmc_req_t reqbuf;
|
||||||
|
|
||||||
|
// If SDSC convert block address to byte address.
|
||||||
|
if (!storage->has_sector_access)
|
||||||
|
sector <<= 9;
|
||||||
|
|
||||||
sdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0);
|
sdmmc_init_cmd(&cmdbuf, is_write ? MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK, sector, SDMMC_RSP_TYPE_1, 0);
|
||||||
|
|
||||||
reqbuf.buf = buf;
|
reqbuf.buf = buf;
|
||||||
|
@ -694,53 +698,54 @@ static int _sd_storage_execute_app_cmd_type1(sdmmc_storage_t *storage, u32 *resp
|
||||||
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0);
|
return _sdmmc_storage_execute_cmd_type1_ex(storage, resp, cmd, arg, check_busy, expected_state, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage)
|
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
u16 vhd_pattern = SD_VHD_27_36 | 0xAA;
|
u16 vhd_pattern = SD_VHD_27_36 | 0xAA;
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_5, 0);
|
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_5, 0);
|
||||||
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
if (!sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
|
||||||
return 1; // The SD Card is version 1.X
|
{
|
||||||
|
*is_sdsc = 1; // The SD Card is version 1.X
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Card version is >= 2.0, parse results.
|
// For Card version >= 2.0, parse results.
|
||||||
u32 resp = 0;
|
u32 resp = 0;
|
||||||
if (!sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5))
|
sdmmc_get_rsp(storage->sdmmc, &resp, 4, SDMMC_RSP_TYPE_5);
|
||||||
return 2; // Failed.
|
|
||||||
|
|
||||||
// Check if VHD was accepted and pattern was properly returned.
|
// Check if VHD was accepted and pattern was properly returned.
|
||||||
if ((resp & 0xFFF) == vhd_pattern)
|
if ((resp & 0xFFF) == vhd_pattern)
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
// Failed.
|
return 0;
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, int is_version_1, int bus_uhs_support)
|
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, bool is_sdsc, int bus_uhs_support)
|
||||||
{
|
{
|
||||||
sdmmc_cmd_t cmdbuf;
|
sdmmc_cmd_t cmdbuf;
|
||||||
// Support for Current > 150mA
|
// Support for Current > 150mA
|
||||||
u32 arg = !is_version_1 ? SD_OCR_XPC : 0;
|
u32 arg = !is_sdsc ? SD_OCR_XPC : 0;
|
||||||
// Support for handling block-addressed SDHC cards
|
// Support for handling block-addressed SDHC cards
|
||||||
arg |= !is_version_1 ? SD_OCR_CCS : 0;
|
arg |= !is_sdsc ? SD_OCR_CCS : 0;
|
||||||
// Support for 1.8V
|
// Support for 1.8V
|
||||||
arg |= (bus_uhs_support && !is_version_1) ? SD_OCR_S18R : 0;
|
arg |= (bus_uhs_support && !is_sdsc) ? SD_OCR_S18R : 0;
|
||||||
// This is needed for most cards. Do not set bit7 even if 1.8V is supported.
|
// This is needed for most cards. Do not set bit7 even if 1.8V is supported.
|
||||||
arg |= SD_OCR_VDD_32_33;
|
arg |= SD_OCR_VDD_32_33;
|
||||||
sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
|
sdmmc_init_cmd(&cmdbuf, SD_APP_OP_COND, arg, SDMMC_RSP_TYPE_3, 0);
|
||||||
if (!_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_version_1 ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
|
if (!_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sdsc ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);
|
return sdmmc_get_rsp(storage->sdmmc, cond, 4, SDMMC_RSP_TYPE_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, int is_version_1, int bus_uhs_support)
|
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sdsc, int bus_uhs_support)
|
||||||
{
|
{
|
||||||
u32 timeout = get_tmr_ms() + 1500;
|
u32 timeout = get_tmr_ms() + 1500;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
u32 cond = 0;
|
u32 cond = 0;
|
||||||
if (!_sd_storage_get_op_cond_once(storage, &cond, is_version_1, bus_uhs_support))
|
if (!_sd_storage_get_op_cond_once(storage, &cond, is_sdsc, bus_uhs_support))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Check if power up is done.
|
// Check if power up is done.
|
||||||
|
@ -1222,6 +1227,7 @@ static void _sd_storage_parse_csd(sdmmc_storage_t *storage)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);
|
storage->csd.capacity = (1 + unstuff_bits(raw_csd, 62, 12)) << (unstuff_bits(raw_csd, 47, 3) + 2);
|
||||||
|
storage->csd.capacity <<= unstuff_bits(raw_csd, 80, 4) - 9; // Convert native block size to LBA 512B.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -1266,7 +1272,7 @@ void sdmmc_storage_init_wait_sd()
|
||||||
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
|
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
|
||||||
{
|
{
|
||||||
u32 tmp = 0;
|
u32 tmp = 0;
|
||||||
int is_version_1 = 0;
|
int is_sdsc = 0;
|
||||||
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
u8 *buf = (u8 *)SDMMC_UPPER_BUFFER;
|
||||||
bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type);
|
bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type);
|
||||||
|
|
||||||
|
@ -1288,12 +1294,11 @@ DPRINTF("[SD] after init\n");
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] went to idle state\n");
|
DPRINTF("[SD] went to idle state\n");
|
||||||
|
|
||||||
is_version_1 = _sd_storage_send_if_cond(storage);
|
if (!_sd_storage_send_if_cond(storage, &is_sdsc))
|
||||||
if (is_version_1 == 2) // Failed.
|
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] after send if cond\n");
|
DPRINTF("[SD] after send if cond\n");
|
||||||
|
|
||||||
if (!_sd_storage_get_op_cond(storage, is_version_1, bus_uhs_support))
|
if (!_sd_storage_get_op_cond(storage, is_sdsc, bus_uhs_support))
|
||||||
return 0;
|
return 0;
|
||||||
DPRINTF("[SD] got op cond\n");
|
DPRINTF("[SD] got op cond\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue