bdk: sdmmc: add UHS DDR50 support

But disable it by default in the auto selection.
This commit is contained in:
CTCaer 2023-03-31 08:23:10 +03:00
parent 76a5facbc3
commit 25be98b7e3
2 changed files with 26 additions and 19 deletions

View file

@ -1038,7 +1038,7 @@ DPRINTF("[SD] power limit defaulted to 720 mW\n");
} }
} }
static int _sd_storage_enable_highspeed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf) static int _sd_storage_set_card_bus_speed(sdmmc_storage_t *storage, u32 hs_type, u8 *buf)
{ {
if (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, SD_SWITCH_GRP_ACCESS, hs_type)) if (!_sd_storage_switch(storage, buf, SD_SWITCH_CHECK, SD_SWITCH_GRP_ACCESS, hs_type))
return 0; return 0;
@ -1115,31 +1115,34 @@ static int _sd_storage_enable_uhs_low_volt(sdmmc_storage_t *storage, u32 type, u
break; break;
} }
/* /*
case SDHCI_TIMING_UHS_DDR50:
if (access_mode & SD_MODE_UHS_DDR50)
{
type = SDHCI_TIMING_UHS_DDR50;
hs_type = UHS_DDR50_BUS_SPEED;
DPRINTF("[SD] setting bus speed to DDR50\n");
storage->csd.busspeed = 50;
break;
}
*/
case SDHCI_TIMING_UHS_SDR25: case SDHCI_TIMING_UHS_SDR25:
if (access_mode & SD_MODE_UHS_SDR25) if (access_mode & SD_MODE_UHS_SDR25)
{ {
type = SDHCI_TIMING_UHS_SDR25; type = SDHCI_TIMING_UHS_SDR25;
hs_type = UHS_SDR25_BUS_SPEED; hs_type = UHS_SDR25_BUS_SPEED;
DPRINTF("[SD] bus speed set to SDR25\n"); DPRINTF("[SD] setting bus speed to SDR25\n");
storage->csd.busspeed = 25; storage->csd.busspeed = 25;
break; break;
} }
*/
case SDHCI_TIMING_UHS_SDR12:
if (!(access_mode & SD_MODE_UHS_SDR12))
return 0;
type = SDHCI_TIMING_UHS_SDR12;
hs_type = UHS_SDR12_BUS_SPEED;
DPRINTF("[SD] bus speed set to SDR12\n");
storage->csd.busspeed = 12;
break;
default: default:
return 0; DPRINTF("[SD] bus speed defaulted to SDR12\n");
break; storage->csd.busspeed = 12;
return 1;
} }
if (!_sd_storage_enable_highspeed(storage, hs_type, buf)) // Setup and set selected card and bus speed.
if (!_sd_storage_set_card_bus_speed(storage, hs_type, buf))
return 0; return 0;
DPRINTF("[SD] card accepted UHS\n"); DPRINTF("[SD] card accepted UHS\n");
@ -1169,7 +1172,7 @@ static int _sd_storage_enable_hs_high_volt(sdmmc_storage_t *storage, u8 *buf)
if (!(access_mode & SD_MODE_HIGH_SPEED)) if (!(access_mode & SD_MODE_HIGH_SPEED))
return 1; return 1;
if (!_sd_storage_enable_highspeed(storage, HIGH_SPEED_BUS_SPEED, buf)) if (!_sd_storage_set_card_bus_speed(storage, HIGH_SPEED_BUS_SPEED, buf))
return 0; return 0;
if (!_sdmmc_storage_check_status(storage)) if (!_sdmmc_storage_check_status(storage))

View file

@ -108,7 +108,7 @@ void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width)
void sdmmc_save_tap_value(sdmmc_t *sdmmc) void sdmmc_save_tap_value(sdmmc_t *sdmmc)
{ {
sdmmc->venclkctl_tap = sdmmc->regs->venclkctl >> 16; sdmmc->venclkctl_tap = (sdmmc->regs->venclkctl & 0xFF0000) >> 16;
sdmmc->venclkctl_set = 1; sdmmc->venclkctl_set = 1;
} }
@ -331,7 +331,6 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
case SDHCI_TIMING_UHS_SDR50: // T210 Errata: the host must be set to SDR104 to WAR a CRC issue. 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_SDR104:
case SDHCI_TIMING_UHS_SDR82: case SDHCI_TIMING_UHS_SDR82:
case SDHCI_TIMING_UHS_DDR50:
case SDHCI_TIMING_MMC_HS100: case SDHCI_TIMING_MMC_HS100:
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR104_BUS_SPEED; sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR104_BUS_SPEED;
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
@ -351,6 +350,11 @@ int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR12_BUS_SPEED; sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR12_BUS_SPEED;
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180; sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
break; break;
case SDHCI_TIMING_UHS_DDR50:
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_DDR50_BUS_SPEED;
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
break;
} }
_sdmmc_commit_changes(sdmmc); _sdmmc_commit_changes(sdmmc);
@ -664,7 +668,6 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
switch (type) switch (type)
{ {
case SDHCI_TIMING_MMC_HS200: case SDHCI_TIMING_MMC_HS200:
case SDHCI_TIMING_MMC_HS400:
case SDHCI_TIMING_UHS_SDR104: case SDHCI_TIMING_UHS_SDR104:
case SDHCI_TIMING_UHS_SDR82: case SDHCI_TIMING_UHS_SDR82:
num_iter = 128; num_iter = 128;
@ -672,12 +675,13 @@ int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
break; break;
case SDHCI_TIMING_UHS_SDR50: case SDHCI_TIMING_UHS_SDR50:
case SDHCI_TIMING_UHS_DDR50: case SDHCI_TIMING_UHS_DDR50: // HW tuning is not supported on DDR modes. But it sets tap to 0 which is proper.
case SDHCI_TIMING_MMC_HS100: case SDHCI_TIMING_MMC_HS100:
num_iter = 256; num_iter = 256;
flag = (4 << 13); // 256 iterations. flag = (4 << 13); // 256 iterations.
break; break;
case SDHCI_TIMING_MMC_HS400:
case SDHCI_TIMING_UHS_SDR12: case SDHCI_TIMING_UHS_SDR12:
case SDHCI_TIMING_UHS_SDR25: case SDHCI_TIMING_UHS_SDR25:
return 1; return 1;