diff options
| author | Boyan Karatotev <boyan.karatotev@arm.com> | 2026-09-07 16:13:39 +0000 |
|---|---|---|
| committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2026-09-07 16:13:39 +0000 |
| commit | 90a3c92bab01ef6b849c9b2155e9512f68ac8103 (patch) | |
| tree | fdd8b439bd4d84de757138a0539d304203faf8da /drivers/cadence/emmc/cdns_sdmmc.c | |
| parent | 35cb6dabe9816d8c7b50e172e71ec3a81f1791e7 (diff) | |
| parent | e854d07963c9c632fcd1b0575b21656600d309ce (diff) | |
| download | arm-trusted-firmware-90a3c92bab01ef6b849c9b2155e9512f68ac8103.tar.gz arm-trusted-firmware-90a3c92bab01ef6b849c9b2155e9512f68ac8103.zip | |
Merge changes I10adb924,I6d2f5ed9 into integration
* changes:
fix(cadence): include platform SDMMC configuration
fix(cadence): use device-specific SDMMC default clocks
Diffstat (limited to 'drivers/cadence/emmc/cdns_sdmmc.c')
| -rw-r--r-- | drivers/cadence/emmc/cdns_sdmmc.c | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/drivers/cadence/emmc/cdns_sdmmc.c b/drivers/cadence/emmc/cdns_sdmmc.c index 1dd81f8ed..b984cf5d4 100644 --- a/drivers/cadence/emmc/cdns_sdmmc.c +++ b/drivers/cadence/emmc/cdns_sdmmc.c @@ -427,20 +427,23 @@ void sd_host_oper_mode(enum sd_opr_modes opr_mode) } } -void card_reset(bool power_enable) +void cdns_sdmmc_card_reset(void) { uint32_t reg_value = 0; - /* Reading SRS10 value before writing */ + /* Power off: per SDHCI/JEDEC spec, BVS must be cleared when BP=0 */ reg_value = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS10); + reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP)); + mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value); + mdelay(20); - if (power_enable == true) { - reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP)); - reg_value = ((1 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP)); - } else { - reg_value &= ~((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP)); - } + /* + * BVS=0b111 = 3.3V ; BVS=0b101 = 1.8V + * Using 3.3V for High Speed(SD)/legacy(eMMC) protocol. + */ + reg_value |= ((7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP)); mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS10, reg_value); + mdelay(50); } void high_speed_enable(bool mode) @@ -501,14 +504,8 @@ void sdmmc_host_init(bool uhs2_enable) /** need to implement*/ } - /* Card reset */ - - card_reset(1); - udelay(2500); - card_reset(0); - udelay(2500); - card_reset(1); - udelay(2500); + /* Card reset - for both eMMC and SD card */ + cdns_sdmmc_card_reset(); /* Enable Interrupt Flags*/ mmio_write_32((cdns_params.reg_base + SDHC_CDNS_SRS13), ~0); @@ -558,7 +555,7 @@ int cdns_send_cmd(struct mmc_cmd *cmd) timeout = TIMEOUT; do { udelay(100); - if (--timeout <= 0) { + if (--timeout == 0) { udelay(50); NOTICE("Timeout occur data and cmd line %x\n", mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS09)); @@ -622,10 +619,42 @@ int cdns_send_cmd(struct mmc_cmd *cmd) timeout = TIMEOUT; + /* Wait for command completion or error */ do { udelay(CDNS_TIMEOUT); status = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12); - } while (((status & (INT_CMD_DONE | ERROR_INT)) == 0) && (timeout-- > 0)); + if (--timeout == 0) { + ERROR("Command %u timeout waiting for response\n", + cmd->cmd_idx); + break; + } + } while (((status & (INT_CMD_DONE | ERROR_INT)) == 0)); + + /* For data commands, wait for Data Transfer Over (DTO) or data ready */ + if ((cmd_flags & DATA_PRESENT) != 0U) { + timeout = TIMEOUT; + do { + udelay(100); + status = mmio_read_32(cdns_params.reg_base + + SDHC_CDNS_SRS12); + if (--timeout == 0) { + ERROR("Command %u timeout waiting for data\n", + cmd->cmd_idx); + ERROR("SRS12=0x%08x SRS09=0x%08x\n", + mmio_read_32(cdns_params.reg_base + + SDHC_CDNS_SRS12), + mmio_read_32(cdns_params.reg_base + + SDHC_CDNS_SRS09)); + break; + } + /* + * In ADMA2 mode the controller raises Transfer Complete (bit 1) + * when the DMA finishes, TRAN_COMP. + */ + } while (((status & + (INT_DTO | INT_TXDR | INT_RXDR | TRAN_COMP)) == 0) && + ((status & ERROR_INT) == 0)); + } mmio_write_32(cdns_params.reg_base + SDHC_CDNS_SRS12, (SRS_12_CC_EN)); status_check = mmio_read_32(cdns_params.reg_base + SDHC_CDNS_SRS12) & 0xffff8000; @@ -735,17 +764,23 @@ int cdns_mmc_init(struct cdns_sdmmc_params *params, memcpy(&cdns_params, params, sizeof(struct cdns_sdmmc_params)); + /* + * Set device type before cdns_sd_host_init() so sdmmc_host_init() + * can branch between eMMC and SD card reset sequences. + */ + cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type; + cdns_set_sdmmc_var(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg); result = cdns_sd_host_init(&sdmmc_combo_phy_reg, &sdmmc_sdhc_reg); if (result < 0) { return result; } - cdns_params.cdn_sdmmc_dev_type = info->mmc_dev_type; cdns_params.cdn_sdmmc_dev_mode = SD_DS; + /* Select operating clock based on detected device type */ result = mmc_init(&cdns_sdmmc_ops, params->clk_rate, params->bus_width, - params->flags, info); + params->flags, info); return result; } |
