From e6984a149bcfdaae681dd7364fb732428dc1850f Mon Sep 17 00:00:00 2001 From: CTCaer Date: Thu, 12 Feb 2026 21:53:59 +0200 Subject: [PATCH] bdk: sdmmc: remove dependency to ram for init --- bdk/storage/sdmmc.c | 78 ++++++++++++++++++++------------------ bdk/storage/sdmmc.h | 19 +++++----- bdk/storage/sdmmc_driver.c | 14 +++---- bdk/storage/sdmmc_driver.h | 8 ++-- 4 files changed, 62 insertions(+), 57 deletions(-) diff --git a/bdk/storage/sdmmc.c b/bdk/storage/sdmmc.c index 1791aaad..dba05f81 100644 --- a/bdk/storage/sdmmc.c +++ b/bdk/storage/sdmmc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2025 CTCaer + * Copyright (c) 2018-2026 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -515,42 +515,41 @@ static void _mmc_storage_parse_csd(sdmmc_storage_t *storage) storage->sec_cnt = storage->csd.capacity; } -static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage, u8 *buf) +static void _mmc_storage_parse_ext_csd(sdmmc_storage_t *storage) { - storage->ext_csd.rev = buf[EXT_CSD_REV]; - storage->ext_csd.ext_struct = buf[EXT_CSD_STRUCTURE]; - storage->ext_csd.card_type = buf[EXT_CSD_CARD_TYPE]; - storage->ext_csd.dev_version = *(u16 *)&buf[EXT_CSD_DEVICE_VERSION]; - storage->ext_csd.boot_mult = buf[EXT_CSD_BOOT_MULT]; - storage->ext_csd.rpmb_mult = buf[EXT_CSD_RPMB_MULT]; - //storage->ext_csd.bkops = buf[EXT_CSD_BKOPS_SUPPORT]; - //storage->ext_csd.bkops_en = buf[EXT_CSD_BKOPS_EN]; - //storage->ext_csd.bkops_status = buf[EXT_CSD_BKOPS_STATUS]; + u8 *ext_csd = storage->raw_ext_csd; - storage->ext_csd.pre_eol_info = buf[EXT_CSD_PRE_EOL_INFO]; - storage->ext_csd.dev_life_est_a = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]; - storage->ext_csd.dev_life_est_b = buf[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]; + storage->ext_csd.rev = ext_csd[EXT_CSD_REV]; + storage->ext_csd.ext_struct = ext_csd[EXT_CSD_STRUCTURE]; + storage->ext_csd.card_type = ext_csd[EXT_CSD_CARD_TYPE]; + storage->ext_csd.dev_version = *(u16 *)&ext_csd[EXT_CSD_DEVICE_VERSION]; + storage->ext_csd.boot_mult = ext_csd[EXT_CSD_BOOT_MULT]; + storage->ext_csd.rpmb_mult = ext_csd[EXT_CSD_RPMB_MULT]; - storage->ext_csd.cache_size = buf[EXT_CSD_CACHE_SIZE] | - (buf[EXT_CSD_CACHE_SIZE + 1] << 8) | - (buf[EXT_CSD_CACHE_SIZE + 2] << 16) | - (buf[EXT_CSD_CACHE_SIZE + 3] << 24); + storage->ext_csd.pre_eol_info = ext_csd[EXT_CSD_PRE_EOL_INFO]; + storage->ext_csd.dev_life_est_a = ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]; + storage->ext_csd.dev_life_est_b = ext_csd[EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]; - storage->ext_csd.max_enh_mult = (buf[EXT_CSD_MAX_ENH_SIZE_MULT] | - (buf[EXT_CSD_MAX_ENH_SIZE_MULT + 1] << 8) | - (buf[EXT_CSD_MAX_ENH_SIZE_MULT + 2] << 16)) * - buf[EXT_CSD_HC_WP_GRP_SIZE] * buf[EXT_CSD_HC_ERASE_GRP_SIZE]; + storage->ext_csd.cache_size = ext_csd[EXT_CSD_CACHE_SIZE] | + (ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8) | + (ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16) | + (ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24); - storage->sec_cnt = *(u32 *)&buf[EXT_CSD_SEC_CNT]; + storage->ext_csd.max_enh_mult = (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT] | + (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT + 1] << 8) | + (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT + 2] << 16)) * + ext_csd[EXT_CSD_HC_WP_GRP_SIZE] * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + + storage->sec_cnt = *(u32 *)&ext_csd[EXT_CSD_SEC_CNT]; } -int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf) +int mmc_storage_get_ext_csd(sdmmc_storage_t *storage) { sdmmc_cmd_t cmdbuf; sdmmc_init_cmd(&cmdbuf, MMC_SEND_EXT_CSD, 0, SDMMC_RSP_TYPE_1, 0); sdmmc_req_t reqbuf; - reqbuf.buf = buf; + reqbuf.buf = storage->raw_ext_csd; reqbuf.blksize = SDMMC_DAT_BLOCKSIZE; reqbuf.num_sectors = 1; reqbuf.is_write = 0; @@ -562,7 +561,7 @@ int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf) u32 tmp = 0; sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1); - _mmc_storage_parse_ext_csd(storage, buf); + _mmc_storage_parse_ext_csd(storage); return _sdmmc_storage_check_card_status(tmp); } @@ -780,7 +779,7 @@ int sdmmc_storage_init_mmc(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_wid return 0; DPRINTF("[MMC] switched buswidth\n"); - if (!mmc_storage_get_ext_csd(storage, (u8 *)SDMMC_ALT_DMA_BUFFER)) + if (!mmc_storage_get_ext_csd(storage)) return 0; DPRINTF("[MMC] got ext_csd\n"); @@ -1123,8 +1122,10 @@ static void _sd_storage_parse_scr(sdmmc_storage_t *storage) } } -int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf) +int sd_storage_get_scr(sdmmc_storage_t *storage) { + u8 buf[8] __attribute__ ((aligned(SDMMC_ADMA_ADDR_ALIGN))); + sdmmc_cmd_t cmdbuf; sdmmc_init_cmd(&cmdbuf, SD_APP_SEND_SCR, 0, SDMMC_RSP_TYPE_1, 0); @@ -1142,7 +1143,7 @@ int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf) u32 tmp = 0; sdmmc_get_cached_rsp(storage->sdmmc, &tmp, SDMMC_RSP_TYPE_1); //Prepare buffer for unstuff_bits - for (u32 i = 0; i < 8; i+=4) + for (u32 i = 0; i < 8; i += 4) { storage->raw_scr[i + 3] = buf[i]; storage->raw_scr[i + 2] = buf[i + 1]; @@ -1383,9 +1384,10 @@ int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *fm return 1; } -static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u8 *buf) +static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type) { sd_func_modes_t fmodes; + u8 *buf = storage->raw_ext_csd; if (sdmmc_get_bus_width(storage->sdmmc) != SDMMC_BUS_WIDTH_4) return 0; @@ -1490,9 +1492,10 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u return _sdmmc_storage_check_status(storage); } -static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf) +static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage) { sd_func_modes_t fmodes; + u8 *buf = storage->raw_ext_csd; if (!sd_storage_get_fmodes(storage, buf, &fmodes)) return 0; @@ -1673,9 +1676,11 @@ void sd_storage_get_ext_regs(sdmmc_storage_t *storage, u8 *buf) _sd_storage_parse_ext_reg(storage, buf, &addr_next); } -int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf) +int sd_storage_get_ssr(sdmmc_storage_t *storage) { sdmmc_cmd_t cmdbuf; + u8 *buf = storage->raw_ext_csd; + sdmmc_init_cmd(&cmdbuf, SD_APP_SD_STATUS, 0, SDMMC_RSP_TYPE_1, 0); sdmmc_req_t reqbuf; @@ -1797,7 +1802,6 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt { u32 tmp = 0; bool is_sdsc = 0; - u8 *buf = (u8 *)SDMMC_ALT_DMA_BUFFER; bool bus_uhs_support = _sdmmc_storage_get_bus_uhs_support(bus_width, type); DPRINTF("[SD]-[init: bus: %d, type: %d]\n", bus_width, type); @@ -1861,7 +1865,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt return 0; DPRINTF("[SD] cleared card detect\n"); - if (!sd_storage_get_scr(storage, buf)) + if (!sd_storage_get_scr(storage)) return 0; DPRINTF("[SD] got scr\n"); @@ -1882,13 +1886,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, buf)) + if (!_sd_storage_enable_uhs_low_volt(storage, type)) return 0; 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. { - if (!_sd_storage_enable_hs_high_volt(storage, buf)) + if (!_sd_storage_enable_hs_high_volt(storage)) return 0; DPRINTF("[SD] enabled HS\n"); @@ -1905,7 +1909,7 @@ int sdmmc_storage_init_sd(sdmmc_storage_t *storage, sdmmc_t *sdmmc, u32 bus_widt } // Parse additional card info from sd status. - if (sd_storage_get_ssr(storage, buf)) + if (sd_storage_get_ssr(storage)) { DPRINTF("[SD] got sd status\n"); } diff --git a/bdk/storage/sdmmc.h b/bdk/storage/sdmmc.h index e1b3fcda..2e40c62f 100644 --- a/bdk/storage/sdmmc.h +++ b/bdk/storage/sdmmc.h @@ -143,9 +143,6 @@ typedef struct _mmc_csd typedef struct _mmc_ext_csd { - //u8 bkops; /* background support bit */ - //u8 bkops_en; /* manual bkops enable bit */ - //u8 bkops_status; /* 246 */ u8 rev; u8 ext_struct; /* 194 */ u8 card_type; /* 196 */ @@ -193,6 +190,7 @@ typedef struct _sd_ext_reg_t typedef struct _sdmmc_storage_t { sdmmc_t *sdmmc; + int initialized; int is_low_voltage; int has_sector_access; @@ -200,10 +198,11 @@ typedef struct _sdmmc_storage_t u32 sec_cnt; u32 partition; u32 max_power; - u8 raw_cid[0x10]; - u8 raw_csd[0x10]; - u8 raw_scr[8]; - u8 raw_ssr[0x40]; + u8 raw_cid[0x10] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN))); + u8 raw_csd[0x10] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN))); + u8 raw_scr[8] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN))); + u8 raw_ssr[SDMMC_CMD_BLOCKSIZE] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN))); + u8 raw_ext_csd[SDMMC_DAT_BLOCKSIZE] __attribute__((aligned(SDMMC_ADMA_ADDR_ALIGN))); mmc_cid_t cid; mmc_csd_t csd; mmc_ext_csd_t ext_csd; @@ -232,12 +231,12 @@ int sdmmc_storage_init_gc(sdmmc_storage_t *storage, sdmmc_t *sdmmc); int sdmmc_storage_execute_vendor_cmd(sdmmc_storage_t *storage, u32 arg); int sdmmc_storage_vendor_sandisk_report(sdmmc_storage_t *storage, void *buf); -int mmc_storage_get_ext_csd(sdmmc_storage_t *storage, void *buf); +int mmc_storage_get_ext_csd(sdmmc_storage_t *storage); int sd_storage_get_ext_reg(sdmmc_storage_t *storage, u8 fno, u8 page, u16 offset, u32 len, void *buf); int sd_storage_get_fmodes(sdmmc_storage_t *storage, u8 *buf, sd_func_modes_t *functions); -int sd_storage_get_scr(sdmmc_storage_t *storage, u8 *buf); -int sd_storage_get_ssr(sdmmc_storage_t *storage, u8 *buf); +int sd_storage_get_scr(sdmmc_storage_t *storage); +int sd_storage_get_ssr(sdmmc_storage_t *storage); u32 sd_storage_get_ssr_au(sdmmc_storage_t *storage); void sd_storage_get_ext_regs(sdmmc_storage_t *storage, u8 *buf); diff --git a/bdk/storage/sdmmc_driver.c b/bdk/storage/sdmmc_driver.c index c279ec86..c543f2be 100644 --- a/bdk/storage/sdmmc_driver.c +++ b/bdk/storage/sdmmc_driver.c @@ -612,7 +612,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd, u32 tap) #ifdef BDK_SDMMC_UHS_DDR200_SUPPORT // Set tap if manual tuning. - if (tap != HW_TAP_TUNING) + if (tap != SDMMC_HW_TAP_TUNING) { sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED; sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap << 16); @@ -662,7 +662,7 @@ typedef struct _sdmmc_manual_tuning_t static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *tuning) { - u32 tap_start = INVALID_TAP; + u32 tap_start = SDMMC_INVALID_TAP; u32 win_size = 0; u32 best_tap = 0; u32 best_size = 0; @@ -673,14 +673,14 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t u32 stable = tuning->result[i / 32] & BIT(i % 32); if (stable && !iter_end) { - if (tap_start == INVALID_TAP) + if (tap_start == SDMMC_INVALID_TAP) tap_start = i; win_size++; } else { - if (tap_start != INVALID_TAP) + if (tap_start != SDMMC_INVALID_TAP) { u32 tap_end = !iter_end ? (i - 1) : i; @@ -691,7 +691,7 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t best_size = win_size + iter_end; } - tap_start = INVALID_TAP; + tap_start = SDMMC_INVALID_TAP; win_size = 0; } } @@ -699,7 +699,7 @@ static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *t // Check if failed or window too small. - if (!best_tap || best_size < SAMPLING_WINDOW_SIZE_MIN) + if (!best_tap || best_size < SDMMC_SAMPLE_WIN_SIZE_MIN) return 0; sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN; @@ -799,7 +799,7 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd) for (u32 i = 0; i < num_iter; i++) { - _sdmmc_tuning_execute_once(sdmmc, cmd, HW_TAP_TUNING); + _sdmmc_tuning_execute_once(sdmmc, cmd, SDMMC_HW_TAP_TUNING); if (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING)) break; diff --git a/bdk/storage/sdmmc_driver.h b/bdk/storage/sdmmc_driver.h index 1ce5ffb8..1e10c8b1 100644 --- a/bdk/storage/sdmmc_driver.h +++ b/bdk/storage/sdmmc_driver.h @@ -274,9 +274,11 @@ /*! Helper for SWITCH command argument. */ #define SDMMC_SWITCH(mode, index, value) (((mode) << 24) | ((index) << 16) | ((value) << 8)) -#define HW_TAP_TUNING 0x100 -#define INVALID_TAP 0x100 -#define SAMPLING_WINDOW_SIZE_MIN 8 +#define SDMMC_HW_TAP_TUNING 0x100 +#define SDMMC_INVALID_TAP 0x100 +#define SDMMC_SAMPLE_WIN_SIZE_MIN 8 + +#define SDMMC_ADMA_ADDR_ALIGN 8 /*! SDMMC controller context. */ typedef struct _sdmmc_t