From d873ebf0cd1d5486fd52e77475cb47ffab2c2529 Mon Sep 17 00:00:00 2001 From: CTCaer Date: Tue, 9 Jun 2026 06:57:53 +0300 Subject: [PATCH] sdmmc: refactor ICR/OCR defines And others. Also add some debug prints and move ocr argument to get op cond. --- bdk/storage/sd_def.h | 31 ++++++-- bdk/storage/sdmmc.c | 169 +++++++++++++++++++++++++------------------ 2 files changed, 122 insertions(+), 78 deletions(-) diff --git a/bdk/storage/sd_def.h b/bdk/storage/sd_def.h index 898ac466..403c8d79 100644 --- a/bdk/storage/sd_def.h +++ b/bdk/storage/sd_def.h @@ -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 */ /* diff --git a/bdk/storage/sdmmc.c b/bdk/storage/sdmmc.c index 4cc9f4b0..b3522320 100644 --- a/bdk/storage/sdmmc.c +++ b/bdk/storage/sdmmc.c @@ -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");