diff --git a/bdk/storage/sdmmc_driver.c b/bdk/storage/sdmmc_driver.c index f48845e..ca1dfb0a 100644 --- a/bdk/storage/sdmmc_driver.c +++ b/bdk/storage/sdmmc_driver.c @@ -114,7 +114,7 @@ void sdmmc_save_tap_value(sdmmc_t *sdmmc) static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type) { - const u32 dqs_trim_val = 0x28; + const u32 dqs_trim_val = 40; // 24 if HS533/HS667. const u8 tap_values_t210[4] = { 4, 0, 3, 0 }; u32 tap_val = 0; @@ -122,7 +122,7 @@ static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type) if (type == SDHCI_TIMING_MMC_HS400) sdmmc->regs->vencapover = (sdmmc->regs->vencapover & 0xFFFFC0FF) | (dqs_trim_val << 8); - sdmmc->regs->ventunctl0 &= ~TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW; + sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED; if (type == SDHCI_TIMING_MMC_HS400) { @@ -188,21 +188,21 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power) sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN; } - // Enable E_INPUT power. - if (!(sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD)) + // Enable E_INPUT (SD) or Disable E_PWRD (eMMC) power. + if (!(sdmmc->regs->sdmemcmppadctl & SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD)) { - sdmmc->regs->sdmemcmppadctl |= TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD; + sdmmc->regs->sdmemcmppadctl |= SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD; _sdmmc_commit_changes(sdmmc); usleep(1); } // Enable auto calibration and start auto configuration. - sdmmc->regs->autocalcfg |= TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE | TEGRA_MMC_AUTOCALCFG_AUTO_CAL_START; + sdmmc->regs->autocalcfg |= SDHCI_TEGRA_AUTOCAL_ENABLE | SDHCI_TEGRA_AUTOCAL_START; _sdmmc_commit_changes(sdmmc); usleep(2); u32 timeout = get_tmr_ms() + 10; - while (sdmmc->regs->autocalsts & TEGRA_MMC_AUTOCALSTS_AUTO_CAL_ACTIVE) + while (sdmmc->regs->autocalsts & SDHCI_TEGRA_AUTOCAL_ACTIVE) { if (get_tmr_ms() > timeout) { @@ -225,12 +225,12 @@ static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power) // In case auto calibration fails, we load suggested standard values. if (!timeout) { + sdmmc->regs->autocalcfg &= ~SDHCI_TEGRA_AUTOCAL_ENABLE; _sdmmc_pad_config_fallback(sdmmc, power); - sdmmc->regs->autocalcfg &= ~TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE; } - // Disable E_INPUT to conserve power. - sdmmc->regs->sdmemcmppadctl &= ~TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD; + // Disable E_INPUT (SD) or enable E_PWRD (eMMC) to conserve power. + sdmmc->regs->sdmemcmppadctl &= ~SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD; if (should_enable_sd_clock) sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; @@ -250,11 +250,11 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc) // if (sdmmc->id == SDMMC_4 && sdmmc->card_clock > 208000) // sdmmc->regs->vendllctl0 = sdmmc->regs->vendllctl0 &= 0xFFFFC07F | (0x7C << 7); - sdmmc->regs->vendllcalcfg |= TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE; + sdmmc->regs->vendllcalcfg |= SDHCI_TEGRA_DLLCAL_CALIBRATE; _sdmmc_commit_changes(sdmmc); u32 timeout = get_tmr_ms() + 5; - while (sdmmc->regs->vendllcalcfg & TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE) + while (sdmmc->regs->vendllcalcfg & SDHCI_TEGRA_DLLCAL_CALIBRATE) { if (get_tmr_ms() > timeout) { @@ -264,7 +264,7 @@ static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc) } timeout = get_tmr_ms() + 10; - while (sdmmc->regs->vendllcalcfgsts & TEGRA_MMC_DLLCAL_CFG_STATUS_DLL_ACTIVE) + while (sdmmc->regs->vendllcalcfgsts & SDHCI_TEGRA_DLLCAL_ACTIVE) { if (get_tmr_ms() > timeout) { @@ -279,7 +279,7 @@ out:; return result; } -static void _sdmmc_reset(sdmmc_t *sdmmc) +static void _sdmmc_reset_cmd_data(sdmmc_t *sdmmc) { sdmmc->regs->swrst |= SDHCI_RESET_CMD | SDHCI_RESET_DATA; _sdmmc_commit_changes(sdmmc); @@ -309,7 +309,7 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) _sdmmc_config_tap_val(sdmmc, type); - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); switch (type) { @@ -323,12 +323,12 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) case SDHCI_TIMING_MMC_HS52: case SDHCI_TIMING_SD_HS25: - sdmmc->regs->hostctl |= SDHCI_CTRL_HISPD; // SD only? + sdmmc->regs->hostctl |= SDHCI_CTRL_HISPD; sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180; break; case SDHCI_TIMING_MMC_HS200: - case SDHCI_TIMING_UHS_SDR50: // T210 Errata for SDR50, the host must be set to SDR104. + case SDHCI_TIMING_UHS_SDR50: // T210 Errata: the host must be set to SDR104 to WAR a CRC issue. case SDHCI_TIMING_UHS_SDR104: case SDHCI_TIMING_UHS_SDR82: case SDHCI_TIMING_UHS_DDR50: @@ -338,7 +338,6 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) break; case SDHCI_TIMING_MMC_HS400: - // Non standard. sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | HS400_BUS_SPEED; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; break; @@ -364,13 +363,13 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type) //if divisor != 1 && divisor << 31 -> error - u16 div = divisor >> 1; - divisor = 0; - if (div > 0xFF) - divisor = div >> SDHCI_DIVIDER_SHIFT; + u16 div_lo = divisor >> 1; + u16 div_hi = 0; + if (div_lo > 0xFF) + div_hi = div_lo >> SDHCI_DIV_LO_SHIFT; - sdmmc->regs->clkcon = (sdmmc->regs->clkcon & ~(SDHCI_DIV_MASK | SDHCI_DIV_HI_MASK)) - | (div << SDHCI_DIVIDER_SHIFT) | (divisor << SDHCI_DIVIDER_HI_SHIFT); + sdmmc->regs->clkcon = (sdmmc->regs->clkcon & ~(SDHCI_DIV_MASK | SDHCI_DIV_HI_MASK)) | + (div_lo << SDHCI_DIV_LO_SHIFT) | (div_hi << SDHCI_DIV_HI_SHIFT); // Enable the SD clock again. if (should_enable_sd_clock) @@ -510,7 +509,7 @@ static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat) while (sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT) if (get_tmr_ms() > timeout) { - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); return 0; } @@ -520,7 +519,7 @@ static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat) while (sdmmc->regs->prnsts & SDHCI_DATA_INHIBIT) if (get_tmr_ms() > timeout) { - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); return 0; } } @@ -536,7 +535,7 @@ static int _sdmmc_wait_card_busy(sdmmc_t *sdmmc) while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL)) if (get_tmr_ms() > timeout) { - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); return 0; } @@ -597,8 +596,9 @@ static int _sdmmc_send_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, bool is_data_presen if (is_data_present) cmdflags |= SDHCI_CMD_DATA; + sdmmc->regs->argument = cmd->arg; - sdmmc->regs->cmdreg = (cmd->cmd << 8) | cmdflags; + sdmmc->regs->cmdreg = SDHCI_CMD_IDX(cmd->cmd) | cmdflags; return 1; } @@ -630,7 +630,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd) _sdmmc_commit_changes(sdmmc); usleep(1); - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN; _sdmmc_commit_changes(sdmmc); @@ -648,7 +648,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd) } } - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL; _sdmmc_commit_changes(sdmmc); @@ -659,7 +659,7 @@ static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd) int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd) { - u32 max = 0, flag = 0; + u32 num_iter, flag; switch (type) { @@ -667,14 +667,14 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd) case SDHCI_TIMING_MMC_HS400: case SDHCI_TIMING_UHS_SDR104: case SDHCI_TIMING_UHS_SDR82: - max = 128; + num_iter = 128; flag = (2 << 13); // 128 iterations. break; case SDHCI_TIMING_UHS_SDR50: case SDHCI_TIMING_UHS_DDR50: case SDHCI_TIMING_MMC_DDR100: - max = 256; + num_iter = 256; flag = (4 << 13); // 256 iterations. break; @@ -686,16 +686,17 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd) return 0; } - sdmmc->regs->ventunctl1 = 0; // step_size 1. + sdmmc->regs->ventunctl1 = 0; // step_size 1. + sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries. + sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier. + sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED; - sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries. - sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier. - sdmmc->regs->ventunctl0 |= TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW; sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING; - for (u32 i = 0; i < max; i++) + for (u32 i = 0; i < num_iter; i++) { _sdmmc_tuning_execute_once(sdmmc, cmd); + if (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING)) break; } @@ -723,7 +724,7 @@ static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc) // Enable 32bit addressing if used (sysad. if blkcnt it fallbacks to 16bit). sdmmc->regs->hostctl2 |= SDHCI_HOST_VERSION_4_EN; - if (!(sdmmc->regs->capareg & SDHCI_CAN_64BIT)) + if (!(sdmmc->regs->capareg & SDHCI_CAP_64BIT)) return 0; sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN; @@ -753,8 +754,8 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power) { if (!sdmmc->t210b01) { - off_pd = 123; - off_pu = 123; + off_pd = 0x7B; // -5. + off_pu = 0x7B; // -5. } else { @@ -766,7 +767,7 @@ static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power) { if (!sdmmc->t210b01) { - off_pd = 125; + off_pd = 0x7D; // -3. off_pu = 0; } } @@ -833,7 +834,7 @@ static int _sdmmc_wait_response(sdmmc_t *sdmmc) break; if (result != SDMMC_MASKINT_NOERROR || get_tmr_ms() > timeout) { - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); return 0; } } @@ -920,9 +921,9 @@ static int _sdmmc_config_dma(sdmmc_t *sdmmc, u32 *blkcnt_out, sdmmc_req_t *req) if (blkcnt_out) *blkcnt_out = blkcnt; - u32 trnmode = SDHCI_TRNS_DMA; + u32 trnmode = SDHCI_TRNS_DMA | SDHCI_TRNS_RTYPE_R1; - // Set mulitblock request. + // Set multiblock request. if (req->is_multi_block) trnmode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN; @@ -974,15 +975,17 @@ static int _sdmmc_update_dma(sdmmc_t *sdmmc) if (result != SDMMC_MASKINT_NOERROR) { #ifdef ERROR_EXTRA_PRINTING - EPRINTFARGS("SDMMC%d: %08X!", sdmmc->id + 1, result); + EPRINTFARGS("SDMMC%d: int error!", sdmmc->id + 1); #endif - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); + return 0; } } while (get_tmr_ms() < timeout); } while (sdmmc->regs->blkcnt != blkcnt); - _sdmmc_reset(sdmmc); + _sdmmc_reset_cmd_data(sdmmc); + return 0; } @@ -1287,11 +1290,10 @@ int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type) sdmmc->clock_stopped = 0; // Set default pad IO trimming configuration. - sdmmc->regs->iospare |= 0x80000; // Enable muxing. - sdmmc->regs->veniotrimctl &= 0xFFFFFFFB; // Set Band Gap VREG to supply DLL. + sdmmc->regs->iospare |= BIT(19); // Enable 1 cycle delayed cmd_oen. + sdmmc->regs->veniotrimctl &= ~BIT(2); // Set Band Gap VREG to supply DLL. sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFB) | ((u32)trim_values[sdmmc->id] << 24); - sdmmc->regs->sdmemcmppadctl = - (sdmmc->regs->sdmemcmppadctl & TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK) | vref_sel; + sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & ~SDHCI_TEGRA_PADCTRL_VREF_SEL_MASK) | vref_sel; // Configure auto calibration values. if (!_sdmmc_autocal_config_offset(sdmmc, power)) diff --git a/bdk/storage/sdmmc_driver.h b/bdk/storage/sdmmc_driver.h index b03fcb0..f22f013 100644 --- a/bdk/storage/sdmmc_driver.h +++ b/bdk/storage/sdmmc_driver.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2022 CTCaer + * Copyright (c) 2018-2023 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, @@ -32,11 +32,6 @@ #define SDMMC_POWER_1_8 1 #define SDMMC_POWER_3_3 2 -/*! SDMMC bus widths. */ -#define SDMMC_BUS_WIDTH_1 0 -#define SDMMC_BUS_WIDTH_4 1 -#define SDMMC_BUS_WIDTH_8 2 - /*! SDMMC response types. */ #define SDMMC_RSP_TYPE_0 0 #define SDMMC_RSP_TYPE_1 1 @@ -45,25 +40,30 @@ #define SDMMC_RSP_TYPE_4 4 #define SDMMC_RSP_TYPE_5 5 +/*! SDMMC bus widths. */ +#define SDMMC_BUS_WIDTH_1 0 +#define SDMMC_BUS_WIDTH_4 1 +#define SDMMC_BUS_WIDTH_8 2 + /*! SDMMC mask interrupt status. */ #define SDMMC_MASKINT_MASKED 0 #define SDMMC_MASKINT_NOERROR 1 #define SDMMC_MASKINT_ERROR 2 -/*! SDMMC present state. */ +/*! SDMMC present state. 0x24. */ #define SDHCI_CMD_INHIBIT BIT(0) #define SDHCI_DATA_INHIBIT BIT(1) #define SDHCI_DAT_LINE_ACTIVE BIT(2) #define SDHCI_RETUNING_REQUEST BIT(3) -#define SDHCI_EMMC_LINE_LVL_MASK 0xF0 -#define SDHCI_DATA_4_LVL BIT(4) // eMMC only. -#define SDHCI_DATA_5_LVL BIT(5) // eMMC only. -#define SDHCI_DATA_6_LVL BIT(6) // eMMC only. -#define SDHCI_DATA_7_LVL BIT(7) // eMMC only. +#define SDHCI_EMMC_LINE_LVL_MASK (0xFU << 4) +#define SDHCI_DATA_4_LVL BIT(4) // eMMC only. +#define SDHCI_DATA_5_LVL BIT(5) // eMMC only. +#define SDHCI_DATA_6_LVL BIT(6) // eMMC only. +#define SDHCI_DATA_7_LVL BIT(7) // eMMC only. #define SDHCI_DOING_WRITE BIT(8) -#define SDHCI_DOING_READ BIT(9) // SD only. -#define SDHCI_SPACE_AVAILABLE BIT(10) -#define SDHCI_DATA_AVAILABLE BIT(11) +#define SDHCI_DOING_READ BIT(9) // SD only. +#define SDHCI_SPACE_AVAILABLE BIT(10) // Write buffer empty. +#define SDHCI_DATA_AVAILABLE BIT(11) // Read buffer has data. #define SDHCI_CARD_PRESENT BIT(16) #define SDHCI_CD_STABLE BIT(17) #define SDHCI_CD_LVL BIT(18) @@ -74,18 +74,21 @@ #define SDHCI_DATA_2_LVL BIT(22) #define SDHCI_DATA_3_LVL BIT(23) #define SDHCI_CMD_LVL BIT(24) -#define SDHCI_CMD_NOT_ISSUED BIT(27) -/*! SDMMC transfer mode. */ -#define SDHCI_TRNS_DMA BIT(0) -#define SDHCI_TRNS_BLK_CNT_EN BIT(1) -#define SDHCI_TRNS_AUTO_CMD12 BIT(2) -#define SDHCI_TRNS_AUTO_CMD23 BIT(3) -#define SDHCI_TRNS_WRITE 0x00 // Bit4. -#define SDHCI_TRNS_READ BIT(4) -#define SDHCI_TRNS_MULTI BIT(5) +/*! SDMMC transfer mode. 0x0C. */ +#define SDHCI_TRNS_DMA BIT(0) +#define SDHCI_TRNS_BLK_CNT_EN BIT(1) +#define SDHCI_TRNS_AUTO_CMD12 (1U << 2) +#define SDHCI_TRNS_AUTO_CMD23 (2U << 2) +#define SDHCI_TRNS_WRITE (0U << 4) +#define SDHCI_TRNS_READ BIT(4) +#define SDHCI_TRNS_MULTI BIT(5) +#define SDHCI_TRNS_RTYPE_R1 (0U << 6) +#define SDHCI_TRNS_RTYPE_R5 BIT(6) +#define SDHCI_TRNS_RSP_ERR_CHK BIT(7) +#define SDHCI_TRNS_RSP_INT_DIS BIT(8) -/*! SDMMC command. */ +/*! SDMMC command. 0x0E. */ #define SDHCI_CMD_RESP_MASK 0x3 #define SDHCI_CMD_RESP_NO_RESP 0x0 #define SDHCI_CMD_RESP_LEN136 0x1 @@ -94,77 +97,77 @@ #define SDHCI_CMD_CRC BIT(3) #define SDHCI_CMD_INDEX BIT(4) #define SDHCI_CMD_DATA BIT(5) -#define SDHCI_CMD_ABORTCMD 0xC0 +#define SDHCI_CMD_TYPE_NORMAL (0U << 6) +#define SDHCI_CMD_TYPE_SUSPEND (1U << 6) +#define SDHCI_CMD_TYPE_RESUME (2U << 6) +#define SDHCI_CMD_TYPE_ABORT (3U << 6) +#define SDHCI_CMD_IDX(cmd) ((cmd) << 8) -/*! SDMMC host control. */ + +/*! SDMMC host control. 0x28. */ #define SDHCI_CTRL_LED BIT(0) #define SDHCI_CTRL_4BITBUS BIT(1) // SD only. #define SDHCI_CTRL_HISPD BIT(2) // SD only. -#define SDHCI_CTRL_DMA_MASK 0x18 -#define SDHCI_CTRL_SDMA 0x00 -#define SDHCI_CTRL_ADMA1 0x08 -#define SDHCI_CTRL_ADMA32 0x10 -#define SDHCI_CTRL_ADMA64 0x18 +#define SDHCI_CTRL_DMA_MASK (3U << 3) +#define SDHCI_CTRL_SDMA (0U << 3) +#define SDHCI_CTRL_ADMA1 (1U << 3) +#define SDHCI_CTRL_ADMA32 (2U << 3) +#define SDHCI_CTRL_ADMA64 (3U << 3) #define SDHCI_CTRL_8BITBUS BIT(5) // eMMC only (or UHS-II). #define SDHCI_CTRL_CDTEST_INS BIT(6) #define SDHCI_CTRL_CDTEST_EN BIT(7) -/*! SDMMC host control 2. */ -#define SDHCI_CTRL_UHS_MASK 0x7 -#define SDHCI_CTRL_VDD_180 BIT(3) -#define SDHCI_CTRL_DRV_TYPE_B (0U << 4) -#define SDHCI_CTRL_DRV_TYPE_A (1U << 4) -#define SDHCI_CTRL_DRV_TYPE_C (2U << 4) -#define SDHCI_CTRL_DRV_TYPE_D (3U << 4) -#define SDHCI_CTRL_EXEC_TUNING BIT(6) -#define SDHCI_CTRL_TUNED_CLK BIT(7) -#define SDHCI_HOST_VERSION_4_EN BIT(12) -#define SDHCI_ADDRESSING_64BIT_EN BIT(13) -#define SDHCI_CTRL_PRESET_VAL_EN BIT(15) +/*! SDMMC host control 2. 0x3E. */ +#define SDHCI_CTRL_UHS_MASK 0x7 +#define SDHCI_CTRL_VDD_180 BIT(3) +#define SDHCI_CTRL_DRV_TYPE_B (0U << 4) +#define SDHCI_CTRL_DRV_TYPE_A (1U << 4) +#define SDHCI_CTRL_DRV_TYPE_C (2U << 4) +#define SDHCI_CTRL_DRV_TYPE_D (3U << 4) +#define SDHCI_CTRL_EXEC_TUNING BIT(6) +#define SDHCI_CTRL_TUNED_CLK_SHIFT 7 +#define SDHCI_CTRL_TUNED_CLK BIT(7) +#define SDHCI_HOST_VERSION_4_EN BIT(12) +#define SDHCI_ADDRESSING_64BIT_EN BIT(13) +#define SDHCI_CTRL_PRESET_VAL_EN BIT(15) -/*! SDMMC power control. */ +/*! SDMMC power control. 0x29. */ #define SDHCI_POWER_ON BIT(0) -#define SDHCI_POWER_180 0x0A -#define SDHCI_POWER_300 0x0C -#define SDHCI_POWER_330 0x0E +#define SDHCI_POWER_180 (5U << 1) +#define SDHCI_POWER_300 (6U << 1) +#define SDHCI_POWER_330 (7U << 1) #define SDHCI_POWER_MASK 0xF1 // UHS-II only. -// /*! SDMMC max current. */ -// #define SDHCI_MAX_CURRENT_330_MASK 0xFF -// #define SDHCI_MAX_CURRENT_180_MASK 0xFF0000 -// #define SDHCI_MAX_CURRENT_MULTIPLIER 4 - -/*! SDMMC clock control. */ -#define SDHCI_CLOCK_INT_EN BIT(0) -#define SDHCI_CLOCK_INT_STABLE BIT(1) +/*! SDMMC clock control. 0x2C. */ +#define SDHCI_CLOCK_INT_EN BIT(0) // Internal Clock. +#define SDHCI_CLOCK_INT_STABLE BIT(1) // Internal Clock Stable. #define SDHCI_CLOCK_CARD_EN BIT(2) #define SDHCI_PROG_CLOCK_MODE BIT(5) -#define SDHCI_DIVIDER_HI_SHIFT 6 -#define SDHCI_DIV_HI_MASK (3U << SDHCI_DIVIDER_HI_SHIFT) -#define SDHCI_DIVIDER_SHIFT 8 -#define SDHCI_DIV_MASK (0xFFU << SDHCI_DIVIDER_SHIFT) +#define SDHCI_DIV_HI_SHIFT 6 +#define SDHCI_DIV_HI_MASK (3U << SDHCI_DIV_HI_SHIFT) +#define SDHCI_DIV_LO_SHIFT 8 +#define SDHCI_DIV_MASK (0xFFU << SDHCI_DIV_LO_SHIFT) -/*! SDMMC software reset. */ +/*! SDMMC software reset. 0x2F. */ #define SDHCI_RESET_ALL BIT(0) #define SDHCI_RESET_CMD BIT(1) #define SDHCI_RESET_DATA BIT(2) -/*! SDMMC interrupt status and control. */ +/*! SDMMC interrupt status and control. 0x30/0x34. */ #define SDHCI_INT_RESPONSE BIT(0) #define SDHCI_INT_DATA_END BIT(1) #define SDHCI_INT_BLK_GAP BIT(2) #define SDHCI_INT_DMA_END BIT(3) -#define SDHCI_INT_SPACE_AVAIL BIT(4) -#define SDHCI_INT_DATA_AVAIL BIT(5) +#define SDHCI_INT_SPACE_AVAIL BIT(4) // Write buffer empty. +#define SDHCI_INT_DATA_AVAIL BIT(5) // Read buffer has data. #define SDHCI_INT_CARD_INSERT BIT(6) #define SDHCI_INT_CARD_REMOVE BIT(7) #define SDHCI_INT_CARD_INT BIT(8) #define SDHCI_INT_RETUNE BIT(12) -#define SDHCI_INT_CQE BIT(14) #define SDHCI_INT_ERROR BIT(15) -/*! SDMMC error interrupt status and control. */ +/*! SDMMC error interrupt status and control. 0x32/0x36. */ #define SDHCI_ERR_INT_TIMEOUT BIT(0) #define SDHCI_ERR_INT_CRC BIT(1) #define SDHCI_ERR_INT_END_BIT BIT(2) @@ -173,16 +176,65 @@ #define SDHCI_ERR_INT_DATA_CRC BIT(5) #define SDHCI_ERR_INT_DATA_END_BIT BIT(6) #define SDHCI_ERR_INT_BUS_POWER BIT(7) -#define SDHCI_ERR_INT_AUTO_CMD_ERR BIT(8) -#define SDHCI_ERR_INT_ADMA_ERROR BIT(9) -#define SDHCI_ERR_INT_TUNE_ERROR BIT(10) -#define SDHCI_ERR_INT_RSP_ERROR BIT(11) +#define SDHCI_ERR_INT_AUTO_CMD12 BIT(8) +#define SDHCI_ERR_INT_ADMA BIT(9) +#define SDHCI_ERR_INT_TUNE BIT(10) +#define SDHCI_ERR_INT_RSP BIT(11) +#define SDHCI_ERR_INT_TARGET_RSP BIT(12) +#define SDHCI_ERR_INT_SPI BIT(13) +#define SDHCI_ERR_INT_VND_BOOT_TMO BIT(14) +#define SDHCI_ERR_INT_VND_BOOT_ACK BIT(15) #define SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR \ - (SDHCI_ERR_INT_AUTO_CMD_ERR | SDHCI_ERR_INT_DATA_END_BIT | \ - SDHCI_ERR_INT_DATA_CRC | SDHCI_ERR_INT_DATA_TIMEOUT | \ - SDHCI_ERR_INT_INDEX | SDHCI_ERR_INT_END_BIT | \ - SDHCI_ERR_INT_CRC | SDHCI_ERR_INT_TIMEOUT) + (SDHCI_ERR_INT_AUTO_CMD12 | SDHCI_ERR_INT_DATA_END_BIT | \ + SDHCI_ERR_INT_DATA_CRC | SDHCI_ERR_INT_DATA_TIMEOUT | \ + SDHCI_ERR_INT_INDEX | SDHCI_ERR_INT_END_BIT | \ + SDHCI_ERR_INT_CRC | SDHCI_ERR_INT_TIMEOUT) + +/*! Host Capability 1. 0x40. */ +#define SDHCI_CAP_TM_CLK_FREQ_MASK 0x3F +#define SDHCI_CAP_TM_UNIT_MHZ BIT(7) +#define SDHCI_CAP_BASE_CLK_FREQ_MASK (0xFFU << 8) +#define SDHCI_CAP_MAX_BLK_LEN_MASK (3U << 16) +#define SDHCI_CAP_EMMC_8BIT BIT(18) +#define SDHCI_CAP_ADMA2 BIT(19) +#define SDHCI_CAP_HISPD BIT(21) +#define SDHCI_CAP_SDMA BIT(22) +#define SDHCI_CAP_SUSPEND_RESUME BIT(23) +#define SDHCI_CAP_3_3_V BIT(24) +#define SDHCI_CAP_3_0_V BIT(25) +#define SDHCI_CAP_1_8_V BIT(26) +#define SDHCI_CAP_64BIT BIT(28) +#define SDHCI_CAP_ASYNC_INT BIT(29) +#define SDHCI_CAP_SLOT_TYPE_MASK (3U << 30) +#define SDHCI_CAP_SLOT_TYPE_REMOVABLE (0U << 30) +#define SDHCI_CAP_SLOT_TYPE_EMBEDDED (1U << 30) +#define SDHCI_CAP_SLOT_TYPE_SHARED (2U << 30) +#define SDHCI_CAP_SLOT_TYPE_UHS2 (3U << 30) + +/*! Host Capability 2. 0x44. */ +#define SDHCI_CAP_SDR50 BIT(0) +#define SDHCI_CAP_SDR5104 BIT(1) +#define SDHCI_CAP_DDR50 BIT(2) +#define SDHCI_CAP_UHS2 BIT(3) +#define SDHCI_CAP_DRV_TYPE_A BIT(4) +#define SDHCI_CAP_DRV_TYPE_C BIT(5) +#define SDHCI_CAP_DRV_TYPE_D BIT(6) +#define SDHCI_CAP_RSP_TIMER_CNT_MASK (0xFU << 8) +#define SDHCI_CAP_SDR50_TUNING BIT(13) +#define SDHCI_CAP_RSP_MODES_MASK (3U << 14) +#define SDHCI_CAP_CLK_MULT (0xFFU << 16) +#define SDHCI_CAP_ADMA3 BIT(27) +#define SDHCI_CAP_VDD2_1_8V BIT(28) + +/*! SDMMC max current. 0x48 */ +#define SDHCI_MAX_CURRENT_3_3_V_MASK (0xFFU << 0) +#define SDHCI_MAX_CURRENT_3_0_V_MASK (0xFFU << 8) +#define SDHCI_MAX_CURRENT_1_8_V_MASK (0xFFU << 16) +#define SDHCI_MAX_CURRENT_MULTIPLIER 4 + +/*! SDMMC max current. 0x4C */ +#define SDHCI_MAX_CURRENT_1_8_V_VDD2_MASK (0xFFU << 0) /*! SD bus speeds. */ #define UHS_SDR12_BUS_SPEED 0 @@ -211,8 +263,6 @@ #define SDHCI_TIMING_UHS_SDR82 13 // GC FPGA. Obsolete and Repurposed. MMC_HS50 -> SDR82. #define SDHCI_TIMING_MMC_DDR100 14 // GC ASIC. -#define SDHCI_CAN_64BIT BIT(28) - /*! SDMMC Low power features. */ #define SDMMC_POWER_SAVE_DISABLE 0 #define SDMMC_POWER_SAVE_ENABLE 1 diff --git a/bdk/storage/sdmmc_t210.h b/bdk/storage/sdmmc_t210.h index 50686e4..dfea7d5 100644 --- a/bdk/storage/sdmmc_t210.h +++ b/bdk/storage/sdmmc_t210.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018 naehrwert - * Copyright (c) 2018-2019 CTCaer + * Copyright (c) 2018-2023 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, @@ -21,14 +21,15 @@ #include #include -#define TEGRA_MMC_VNDR_TUN_CTRL0_TAP_VAL_UPDATED_BY_HW 0x20000 -#define TEGRA_MMC_DLLCAL_CFG_EN_CALIBRATE 0x80000000 -#define TEGRA_MMC_DLLCAL_CFG_STATUS_DLL_ACTIVE 0x80000000 -#define TEGRA_MMC_SDMEMCOMPPADCTRL_PAD_E_INPUT_PWRD 0x80000000 -#define TEGRA_MMC_SDMEMCOMPPADCTRL_COMP_VREF_SEL_MASK 0xFFFFFFF0 -#define TEGRA_MMC_AUTOCALCFG_AUTO_CAL_ENABLE 0x20000000 -#define TEGRA_MMC_AUTOCALCFG_AUTO_CAL_START 0x80000000 -#define TEGRA_MMC_AUTOCALSTS_AUTO_CAL_ACTIVE 0x80000000 +#define SDHCI_TEGRA_TUNING_TAP_HW_UPDATED BIT(17) +#define SDHCI_TEGRA_DLLCAL_CALIBRATE BIT(31) +#define SDHCI_TEGRA_DLLCAL_ACTIVE BIT(31) +#define SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD BIT(31) +#define SDHCI_TEGRA_PADCTRL_VREF_SEL_MASK 0xF +#define SDHCI_TEGRA_AUTOCAL_SLW_OVERRIDE BIT(28) +#define SDHCI_TEGRA_AUTOCAL_ENABLE BIT(29) +#define SDHCI_TEGRA_AUTOCAL_START BIT(31) +#define SDHCI_TEGRA_AUTOCAL_ACTIVE BIT(31) typedef struct _t210_sdmmc_t { @@ -72,21 +73,21 @@ typedef struct _t210_sdmmc_t // ADMA3 not supported. 1.8V VDD2 supported. /* 0x44 */ vu32 capareg_hi; -/* 0x48 */ vu32 maxcurr; // Get information by another method. Can be overriden via maxcurrover and maxcurrover_hi. -/* 0x4C */ vu8 rsvd0[4]; // 4C-4F reserved for more max current. -/* 0x50 */ vu16 setacmd12err; +/* 0x48 */ vu32 maxcurr; // Get information by another method. Can be overriden via maxcurrover and maxcurrover_hi. +/* 0x4C */ vu32 maxcurr_hi; +/* 0x50 */ vu16 setacmd12err; // Force error in acmd12errsts. /* 0x52 */ vu16 setinterr; /* 0x54 */ vu8 admaerr; -/* 0x55 */ vu8 rsvd1[3]; // 55-57 reserved. +/* 0x55 */ vu8 rsvd1[3]; // 55-57 reserved. /* 0x58 */ vu32 admaaddr; /* 0x5C */ vu32 admaaddr_hi; /* 0x60 */ vu16 presets[11]; /* 0x76 */ vu16 rsvd2; /* 0x78 */ vu32 adma3addr; /* 0x7C */ vu32 adma3addr_hi; -/* 0x80 */ vu8 uhs2[124]; // 80-FB UHS-II. +/* 0x80 */ vu8 uhs2[124]; // 80-FB UHS-II. /* 0xFC */ vu16 slotintsts; -/* 0xFE */ vu16 hcver; // 0x303 (4.00). +/* 0xFE */ vu16 hcver; // 0x303 (4.00). /* UHS-II range. Used for Vendor registers here */ /* 0x100 */ vu32 venclkctl;