bdk: sdmmc: remove dependency to ram for init

This commit is contained in:
CTCaer
2026-02-12 21:53:59 +02:00
parent 5cb44753fc
commit e6984a149b
4 changed files with 62 additions and 57 deletions

View File

@@ -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");
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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