summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoyan Karatotev <boyan.karatotev@arm.com>2026-09-07 16:13:39 +0000
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2026-09-07 16:13:39 +0000
commit90a3c92bab01ef6b849c9b2155e9512f68ac8103 (patch)
treefdd8b439bd4d84de757138a0539d304203faf8da
parent35cb6dabe9816d8c7b50e172e71ec3a81f1791e7 (diff)
parente854d07963c9c632fcd1b0575b21656600d309ce (diff)
downloadarm-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
-rw-r--r--drivers/cadence/combo_phy/cdns_combo_phy.c17
-rw-r--r--drivers/cadence/emmc/cdns_sdmmc.c75
-rw-r--r--include/drivers/cadence/cdns_combo_phy.h1
-rw-r--r--include/drivers/cadence/cdns_sdmmc.h12
4 files changed, 65 insertions, 40 deletions
diff --git a/drivers/cadence/combo_phy/cdns_combo_phy.c b/drivers/cadence/combo_phy/cdns_combo_phy.c
index f00d0c100..87f176f9c 100644
--- a/drivers/cadence/combo_phy/cdns_combo_phy.c
+++ b/drivers/cadence/combo_phy/cdns_combo_phy.c
@@ -64,20 +64,3 @@ int cdns_sd_card_detect(void)
return 0;
}
-
-int cdns_emmc_card_reset(void)
-{
- uint32_t _status = 0;
-
- /* Reset embedded card */
- mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP) | _status);
- mdelay(68680); /* ~68680us */
- mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (0 << SDMMC_CDN_BP));
- udelay(340); /* ~340us */
-
- /* Turn on supply voltage */
- /* BVS = 7, BP = 1, BP2 only in UHS2 mode */
- mmio_write_32(SDMMC_CDN(SRS10), (7 << SDMMC_CDN_BVS) | (1 << SDMMC_CDN_BP) | _status);
-
- return 0;
-}
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;
}
diff --git a/include/drivers/cadence/cdns_combo_phy.h b/include/drivers/cadence/cdns_combo_phy.h
index 4d3a75394..8dddbee16 100644
--- a/include/drivers/cadence/cdns_combo_phy.h
+++ b/include/drivers/cadence/cdns_combo_phy.h
@@ -234,6 +234,5 @@ struct cdns_sdmmc_combo_phy {
int cdns_sdmmc_write_phy_reg(uint32_t phy_reg_addr, uint32_t phy_reg_addr_value,
uint32_t phy_reg_data, uint32_t phy_reg_data_value);
int cdns_sd_card_detect(void);
-int cdns_emmc_card_reset(void);
#endif \ No newline at end of file
diff --git a/include/drivers/cadence/cdns_sdmmc.h b/include/drivers/cadence/cdns_sdmmc.h
index f4485ca8d..69ee5a1c9 100644
--- a/include/drivers/cadence/cdns_sdmmc.h
+++ b/include/drivers/cadence/cdns_sdmmc.h
@@ -12,6 +12,8 @@
#include <drivers/cadence/cdns_combo_phy.h>
#include <drivers/mmc.h>
+#include <platform_def.h>
+
#if MMC_DEVICE_TYPE == 0
#define CONFIG_DMA_ADDR_T_64BIT 0
#endif
@@ -446,10 +448,16 @@
#define CONFIG_CDNS_DESC_COUNT 8
/*
- * To accommodate SDMCLK set to 200MHz
- * TODO: To support various clock range
+ * SD card, according to SD Host Controller Simplified Specification
+ * will be using High Speed default 50MHz as we have enabled HS mode.
+ * eMMC, according to JEDEC JESD84-B51, will be using legacy default
+ * 26MHz for max compatibility.
*/
+#if MMC_DEVICE_TYPE == 1
#define SDEMMC_SDCLK 50000000U
+#else
+#define SDEMMC_SDCLK 26000000U
+#endif
enum sd_opcode {
SD_GO_IDLE_STATE = 0,