sdmmc: refactor ICR/OCR defines

And others.
Also add some debug prints and move ocr argument to get op cond.
This commit is contained in:
CTCaer
2026-06-09 06:57:53 +03:00
parent 07f9043bcd
commit d873ebf0cd
2 changed files with 122 additions and 78 deletions

View File

@@ -49,14 +49,33 @@
#define SD_APP_GET_CER_RES1 48 /* adtc R1 */
#define SD_APP_CHANGE_SECURE_AREA 49 /* adtc R1b */
/* ICR bit definitions */
#define SD_ICR_PATTERN 0xAA /* Check pattern */
#define SD_ICR_VHS_27_36 (1U << 8) /* VDD IO voltage 2.7 ~ 3.6 */
#define SD_ICR_VHS_170_195 (2U << 8) /* VDD IO voltage 1.7 ~ 1.95 (LVS-only) */
#define SD_ICR_PCIE (1U << 12) /* PCIE availability */
#define SD_ICR_PCIE_12 (1U << 13) /* PCIE IO voltage 1.2 */
/* OCR bit definitions */
#define SD_OCR_VDD_18 (1U << 7) /* VDD voltage 1.8 */
#define SD_VHS_27_36 (1U << 8) /* VDD voltage 2.7 ~ 3.6 */
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD voltage 3.2 ~ 3.3 */
#define SD_OCR_VDD_170_195 (1U << 7) /* VDD IO voltage 1.7 ~ 1.95 (LVS-only or support) */
#define SD_OCR_VDD_27_28 (1U << 15) /* VDD IO voltage 2.7 ~ 2.8 */
#define SD_OCR_VDD_28_29 (1U << 16) /* VDD IO voltage 2.8 ~ 2.9 */
#define SD_OCR_VDD_29_30 (1U << 17) /* VDD IO voltage 2.9 ~ 3.0 */
#define SD_OCR_VDD_30_31 (1U << 18) /* VDD IO voltage 3.0 ~ 3.1 */
#define SD_OCR_VDD_31_32 (1U << 19) /* VDD IO voltage 3.1 ~ 3.2 */
#define SD_OCR_VDD_32_33 (1U << 20) /* VDD IO voltage 3.2 ~ 3.3 */
#define SD_OCR_VDD_33_34 (1U << 21) /* VDD IO voltage 3.3 ~ 3.4 */
#define SD_OCR_VDD_34_35 (1U << 22) /* VDD IO voltage 3.4 ~ 3.5 */
#define SD_OCR_VDD_35_36 (1U << 23) /* VDD IO voltage 3.5 ~ 3.6 */
#define SD_OCR_S18R (1U << 24) /* 1.8V switching request */
#define SD_ROCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
#define SD_OCR_XPC (1U << 28) /* SDXC power control */
#define SD_OCR_CCS (1U << 30) /* Card Capacity Status */
#define SD_OCR_S18A SD_OCR_S18R /* 1.8V switching accepted by card */
#define SD_OCR_HO2T (1U << 27) /* SDUC support */
#define SD_OCR_CO2T SD_OCR_HO2T /* SDUC Status */
#define SD_OCR_XPC (1U << 28) /* SDXC power control - Max Performance */
#define SD_OCR_FB (1U << 29) /* eSD Fast Boot Support */
#define SD_OCR_UHSII (1U << 29) /* UHS-II Card Status */
#define SD_OCR_HCS (1U << 30) /* Host Capacity Support */
#define SD_OCR_CCS SD_OCR_HCS /* Card Capacity Status */
#define SD_OCR_BUSY (1U << 31) /* Card Power up Status */
/*

View File

@@ -898,23 +898,23 @@ void _sd_storage_debug_print_csd(const u32 *raw_csd)
void _sd_storage_debug_print_scr(const u32 *raw_scr)
{
u32 resp[4];
memcpy(&resp[2], raw_scr, 8);
u32 scr[4];
memcpy(&scr[2], raw_scr, 8);
gfx_printf("\n");
gfx_printf("SCR_STRUCTURE: %X\n", unstuff_bits(resp, 60, 4));
gfx_printf("SD_SPEC: %X\n", unstuff_bits(resp, 56, 4));
gfx_printf("DATA_STAT_AFTER_ERASE: %X\n", unstuff_bits(resp, 55, 1));
gfx_printf("SD_SECURITY: %X\n", unstuff_bits(resp, 52, 3));
gfx_printf("SD_BUS widths: %X\n", unstuff_bits(resp, 48, 4));
gfx_printf("SD_SPEC3: %X\n", unstuff_bits(resp, 47, 1));
gfx_printf("EX_SECURITY: %X\n", unstuff_bits(resp, 43, 4));
gfx_printf("SD_SPEC4: %X\n", unstuff_bits(resp, 42, 1));
gfx_printf("SD_SPECX: %X\n", unstuff_bits(resp, 38, 4));
gfx_printf("CMD_SUPPORT: %X\n", unstuff_bits(resp, 32, 4));
gfx_printf("VENDOR: %08X\n", unstuff_bits(resp, 0, 32));
gfx_printf("--RSVD-- %X\n", unstuff_bits(resp, 36, 2));
gfx_printf("SCR_STRUCTURE: %X\n", unstuff_bits(scr, 60, 4));
gfx_printf("SD_SPEC: %X\n", unstuff_bits(scr, 56, 4));
gfx_printf("DATA_STAT_AFTER_ERASE: %X\n", unstuff_bits(scr, 55, 1));
gfx_printf("SD_SECURITY: %X\n", unstuff_bits(scr, 52, 3));
gfx_printf("SD_BUS widths: %X\n", unstuff_bits(scr, 48, 4));
gfx_printf("SD_SPEC3: %X\n", unstuff_bits(scr, 47, 1));
gfx_printf("EX_SECURITY: %X\n", unstuff_bits(scr, 43, 4));
gfx_printf("SD_SPEC4: %X\n", unstuff_bits(scr, 42, 1));
gfx_printf("SD_SPECX: %X\n", unstuff_bits(scr, 38, 4));
gfx_printf("CMD_SUPPORT: %X\n", unstuff_bits(scr, 32, 4));
gfx_printf("VENDOR: %08X\n", unstuff_bits(scr, 0, 32));
gfx_printf("--RSVD-- %X\n", unstuff_bits(scr, 36, 2));
}
void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
@@ -969,75 +969,90 @@ void _sd_storage_debug_print_ssr(const u8 *raw_ssr)
}
#endif
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sdsc)
static int _sd_storage_send_if_cond(sdmmc_storage_t *storage, bool *is_sd_v1)
{
sdmmc_cmd_t cmdbuf;
u16 vhd_pattern = SD_VHS_27_36 | 0xAA;
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, vhd_pattern, SDMMC_RSP_TYPE_7, 0);
u16 icr = SD_ICR_VHS_27_36 | SD_ICR_PATTERN;
sdmmc_init_cmd(&cmdbuf, SD_SEND_IF_COND, icr, SDMMC_RSP_TYPE_7, 0);
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
{
// The SD Card is version 1.X (SDSC) if there is no response.
// The SD Card is version 1.XX if there is no response.
if (storage->sdmmc->error_sts == SDHCI_ERR_INT_CMD_TIMEOUT)
{
*is_sdsc = 1;
*is_sd_v1 = true;
return 0;
}
return 1;
}
// For Card version >= 2.0, parse results.
u32 resp = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_7);
// For version >= 2.0, parse results.
u32 ricr = 0;
sdmmc_get_cached_rsp(storage->sdmmc, &ricr, SDMMC_RSP_TYPE_7);
// Check if VHD was accepted and pattern was properly returned.
if ((resp & 0xFFF) == vhd_pattern)
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
gfx_printf("ICR: %08X -> %08X\n", icr, ricr);
#endif
// Check if VHS was accepted and pattern was properly returned.
if ((ricr & 0xFFF) == (icr & 0xFFF))
return 0;
return 1;
}
static int _sd_storage_get_op_cond_once(sdmmc_storage_t *storage, u32 *cond, bool is_sdsc, int bus_uhs_support)
static int _sd_storage_send_op_cond(sdmmc_storage_t *storage, u32 *rocr, u32 ocr, bool is_sd_v1)
{
sdmmc_cmd_t cmdbuf;
// Support for Current > 150mA.
u32 arg = !is_sdsc ? SD_OCR_XPC : 0;
// Support for handling block-addressed SDHC cards.
arg |= !is_sdsc ? SD_OCR_CCS : 0;
// Support for 1.8V signaling.
arg |= (bus_uhs_support && !is_sdsc) ? SD_OCR_S18R : 0;
// Support for 3.3V power supply (VDD1).
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, ocr, SDMMC_RSP_TYPE_3, 0);
if (_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sdsc ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
if (_sd_storage_execute_app_cmd(storage, R1_SKIP_STATE_CHECK, is_sd_v1 ? R1_ILLEGAL_COMMAND : 0, &cmdbuf, NULL, NULL))
return 1;
return sdmmc_get_cached_rsp(storage->sdmmc, cond, SDMMC_RSP_TYPE_3);
return sdmmc_get_cached_rsp(storage->sdmmc, rocr, SDMMC_RSP_TYPE_3);
}
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sdsc, int bus_uhs_support)
static int _sd_storage_get_op_cond(sdmmc_storage_t *storage, bool is_sd_v1, int lv_support)
{
u32 timeout = get_tmr_ms() + 1500;
// Host in 3.3V power supply (VDD1).
u32 ocr = SD_OCR_VDD_32_33;
if (!is_sd_v1)
{
// Support for Current > 150mA.
ocr |= SD_OCR_XPC;
// Support for handling block-addressed SDHC/SDXC/SDUC cards.
ocr |= SD_OCR_HCS;
// Support and request 1.8V signaling.
ocr |= lv_support ? SD_OCR_S18R : 0;
}
while (true)
{
u32 cond = 0;
if (_sd_storage_get_op_cond_once(storage, &cond, is_sdsc, bus_uhs_support))
u32 rocr = 0;
if (_sd_storage_send_op_cond(storage, &rocr, ocr, is_sd_v1))
break;
// Check if power up is done.
if (cond & SD_OCR_BUSY)
if (rocr & SD_OCR_BUSY)
{
DPRINTF("[SD] op cond: %08X, lv: %d\n", cond, bus_uhs_support);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
gfx_printf("ROCR: %08X (%d)\n", rocr, lv_support);
#else
DPRINTF("[SD] rocr: %08X, lv: %d\n", rocr, lv_support);
#endif
// Check if card is high capacity.
if (cond & SD_OCR_CCS)
storage->has_sector_access = 1;
// Check if card is higher capacity.
if (rocr & SD_OCR_CCS)
storage->has_sector_access = 1; // Non-SDUC.
// Check if card supports 1.8V signaling.
if (cond & SD_ROCR_S18A && bus_uhs_support && !storage->is_low_voltage)
// Check if card accepted 1.8V signaling.
if (rocr & SD_OCR_S18A && lv_support)
{
// Switch to 1.8V signaling.
if (!_sdmmc_storage_execute_cmd_type1(storage, SD_SWITCH_VOLTAGE, 0, 0, R1_STATE_READY))
@@ -1080,13 +1095,13 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
if (sdmmc_execute_cmd(storage->sdmmc, &cmdbuf, NULL, NULL))
break;
u32 resp = 0;
if (sdmmc_get_cached_rsp(storage->sdmmc, &resp, SDMMC_RSP_TYPE_6))
u32 rca = 0;
if (sdmmc_get_cached_rsp(storage->sdmmc, &rca, SDMMC_RSP_TYPE_6))
break;
if (resp >> 16)
if (rca >> 16)
{
storage->rca = resp >> 16;
storage->rca = rca >> 16;
return 0;
}
@@ -1101,27 +1116,27 @@ static int _sd_storage_get_rca(sdmmc_storage_t *storage)
static void _sd_storage_parse_scr(sdmmc_storage_t *storage)
{
// unstuff_bits can parse only 4 u32
u32 resp[4];
u32 scr[4];
memcpy(&resp[2], storage->raw_scr, 8);
memcpy(&scr[2], storage->raw_scr, 8);
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
_sd_storage_debug_print_scr((u32 *)storage->raw_scr);
#endif
storage->scr.sda_vsn = unstuff_bits(resp, 56, 4);
storage->scr.bus_widths = unstuff_bits(resp, 48, 4);
storage->scr.sda_vsn = unstuff_bits(scr, 56, 4);
storage->scr.bus_widths = unstuff_bits(scr, 48, 4);
// If v2.0 is supported, check if Physical Layer Spec v3.0 is supported.
if (storage->scr.sda_vsn == SCR_SPEC_VER_2)
storage->scr.sda_spec3 = unstuff_bits(resp, 47, 1);
storage->scr.sda_spec3 = unstuff_bits(scr, 47, 1);
if (storage->scr.sda_spec3)
{
u8 sda_spec4 = unstuff_bits(resp, 42, 1);
u8 sda_spec4 = unstuff_bits(scr, 42, 1);
if (sda_spec4)
storage->scr.cmds = unstuff_bits(resp, 32, 4);
storage->scr.cmds = unstuff_bits(scr, 32, 4);
else
storage->scr.cmds = unstuff_bits(resp, 32, 2);
storage->scr.cmds = unstuff_bits(scr, 32, 2);
}
}
@@ -1158,7 +1173,7 @@ int sd_storage_get_scr(sdmmc_storage_t *storage)
return _sdmmc_storage_check_card_status(tmp);
}
static int _sd_storage_switch_get(sdmmc_storage_t *storage, void *buf)
static int _sd_storage_switch_get_all(sdmmc_storage_t *storage, void *buf)
{
sdmmc_cmd_t cmdbuf;
sdmmc_init_cmd(&cmdbuf, SD_SWITCH, 0xFFFFFF, SDMMC_RSP_TYPE_1, 0);
@@ -1378,9 +1393,19 @@ int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fm
if (!buf)
buf = (u8 *)SDMMC_ALT_DMA_BUFFER;
if (_sd_storage_switch_get(storage, buf))
if (_sd_storage_switch_get_all(storage, buf))
return 1;
#ifdef SDMMC_DEBUG_PRINT_SD_REGS
gfx_printf("\nFMD: %04X %04X %04X %04X %04X %04X\n",
buf[13] | (buf[12] << 8),
buf[11] | (buf[10] << 8),
buf[9] | (buf[8] << 8),
buf[7] | (buf[6] << 8),
buf[5] | (buf[4] << 8),
buf[3] | (buf[2] << 8));
#endif
fmodes->access_mode = buf[13] | (buf[12] << 8);
fmodes->cmd_system = buf[11] | (buf[10] << 8);
fmodes->driver_strength = buf[9] | (buf[8] << 8);
@@ -1389,7 +1414,7 @@ int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fm
return 0;
}
static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type)
static int _sd_storage_set_uhs_bus_speed(sdmmc_storage_t *storage, u32 type)
{
sd_func_modes_t fmodes;
u8 *buf = storage->raw_ext_csd;
@@ -1497,7 +1522,7 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type)
return _sdmmc_storage_check_status(storage);
}
static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage)
static int _sd_storage_set_hs25_bus_speed(sdmmc_storage_t *storage)
{
sd_func_modes_t fmodes;
u8 *buf = storage->raw_ext_csd;
@@ -1806,9 +1831,9 @@ void sdmmc_storage_init_wait_sd()
int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_width, u32 type)
{
u32 tmp = 0;
bool is_sdsc = 0;
bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type);
u32 tmp = 0;
bool is_sd_v1 = false;
bool lv_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type);
DPRINTF("[SD]-[init: bus: %d, type: %d]\n", bus_width, type);
@@ -1829,11 +1854,11 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
return 1;
DPRINTF("[SD] went to idle state\n");
if (_sd_storage_send_if_cond(storage, &is_sdsc))
if (_sd_storage_send_if_cond(storage, &is_sd_v1))
return 1;
DPRINTF("[SD] after send if cond\n");
DPRINTF("[SD] sent if cond\n");
if (_sd_storage_get_op_cond(storage, is_sdsc, bus_uhs_support))
if (_sd_storage_get_op_cond(storage, is_sd_v1, lv_support))
return 1;
DPRINTF("[SD] got op cond\n");
@@ -1855,7 +1880,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
{
if (sdmmc_setup_clock(storage->sdmmc, SDHCI_TIMING_SD_DS12))
return 1;
DPRINTF("[SD] after setup default clock\n");
DPRINTF("[SD] after setup default hs clock\n");
}
if (_sdmmc_storage_select_card(storage))
@@ -1892,13 +1917,13 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt
if (storage->is_low_voltage)
{
if (_sd_storage_enable_uhs_low_volt(storage, type))
if (_sd_storage_set_uhs_bus_speed(storage, type))
return 1;
DPRINTF("[SD] enabled UHS\n");
}
else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default speed and not SD Version 1.0.
else if (type != SDHCI_TIMING_SD_DS12 && storage->scr.sda_vsn) // Not default HS speed and not SD Version 1.0.
{
if (_sd_storage_enable_hs_high_volt(storage))
if (_sd_storage_set_hs25_bus_speed(storage))
return 1;
DPRINTF("[SD] enabled HS\n");