From 4381d7bb3327938373dafe6b96cb98fbc5c26a49 Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 20 Jul 2025 19:00:26 +0200 Subject: [PATCH 1/4] mmc: s5p_sdhci: remove duplicated card detect code The common sdhci infrastructure is already parsing the cd-gpios property, since commit 451931ea7002 ("mmc: sdhci: Read cd-gpio from devicetree"). The s5p code is therefore duplicated, and also broken since it assumes that the GPIO value is inverted, while the sdhci code correctly follows the ACTIVE_LOW/ACTIVE_HIGH flag specified in the device tree. This fix was originally authored by Simon Shields: https://github.com/fourkbomb/u-boot/commit/2eac9dea7903 The change has been tested on exynos4210-i9100, a device similar to exynos4210-trats. Signed-off-by: Henrik Grimler Reviewed-by: Anand Moon Reviewed-by: Sam Protsenko Signed-off-by: Peng Fan --- drivers/mmc/s5p_sdhci.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 278019f02ab..b2faecefc00 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -141,14 +141,6 @@ static int do_sdhci_init(struct sdhci_host *host) } } - if (dm_gpio_is_valid(&host->cd_gpio)) { - ret = dm_gpio_get_value(&host->cd_gpio); - if (ret) { - debug("no SD card detected (%d)\n", ret); - return -ENODEV; - } - } - return s5p_sdhci_core_init(host); } @@ -183,8 +175,6 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host) gpio_request_by_name_nodev(offset_to_ofnode(node), "pwr-gpios", 0, &host->pwr_gpio, GPIOD_IS_OUT); - gpio_request_by_name_nodev(offset_to_ofnode(node), "cd-gpios", 0, - &host->cd_gpio, GPIOD_IS_IN); return 0; } From 95f8a22e2a8aec2844ed48721e2ec676221fc3d3 Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 20 Jul 2025 19:00:27 +0200 Subject: [PATCH 2/4] mmc: s5p_sdhci: add samsung,exynos4210-sdhci compatible the Exynos4210 devices in u-boot uses samsung,exynos4412-sdhci as sdhci compatible in their DTSes, while the upstream DTSes uses samsung,exynos4210-sdhci. Add samsung,exynos4210-sdhci compatible string for s5p_sdhci driver as well so that it can be used with upstream DTSes. Signed-off-by: Henrik Grimler Reviewed-by: Anand Moon Reviewed-by: Sam Protsenko Signed-off-by: Peng Fan --- drivers/mmc/s5p_sdhci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index b2faecefc00..c80033d8752 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -226,6 +226,7 @@ static int s5p_sdhci_bind(struct udevice *dev) static const struct udevice_id s5p_sdhci_ids[] = { { .compatible = "samsung,exynos4412-sdhci"}, + { .compatible = "samsung,exynos4210-sdhci"}, { } }; From bda1e3f0e7d85ece6bddaed3024e3ef6593482cf Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Sun, 20 Jul 2025 19:00:28 +0200 Subject: [PATCH 3/4] mmc: exynos_dw_mmc: add exynos5420 compatibles The exynos5420 DTSes in linux kernel uses the compatibles samsung,exynos5420-dw-mshc{,-smu} instead of just samsung,exynos-dwmmc. Match the additional compatibles in the driver to make it possible to use it with DTSes from Linux kernel. Signed-off-by: Jaehoon Chung [ grimler: rebase after clksel reg abstraction and re-write commit message ] Signed-off-by: Henrik Grimler Reviewed-by: Sam Protsenko Reviewed-by: Anand Moon Signed-off-by: Peng Fan --- drivers/mmc/exynos_dw_mmc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index c8bf89d6d35..12e37cb4b78 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -372,6 +372,12 @@ static const struct udevice_id exynos_dwmmc_ids[] = { { .compatible = "samsung,exynos4412-dw-mshc", .data = (ulong)&exynos4_drv_data, + }, { + .compatible = "samsung,exynos5420-dw-mshc-smu", + .data = (ulong)&exynos5_drv_data, + }, { + .compatible = "samsung,exynos5420-dw-mshc", + .data = (ulong)&exynos5_drv_data, }, { .compatible = "samsung,exynos-dwmmc", .data = (ulong)&exynos5_drv_data, From 1080815650a00257929f645bedf4e1795bf188bf Mon Sep 17 00:00:00 2001 From: Iulian Banaga Date: Mon, 21 Jul 2025 15:35:00 +0300 Subject: [PATCH 4/4] Fix emmc error state after mmc write timeout This is a fix for the sporadic mmc write failure: mmc write failed 0 blocks written: ERROR After this happens the emmc will remain in an error state where subsequent read/writes fail with a timeout. The mmc driver sends CMD25 - WRITE_MULTIPLE_BLOCK which can sporadically timeout. When this happens, the mmc driver aborts the transfer and returns the above error messages. But the emmc still remains in data transfer mode, since the timeout was decided by uboot, not by the emmc. Fix this by sending the STOP_TRANSMISSION command (CMD12) and waiting for the emmc to be in ready state again (CMD13). Transferring data blocks after a CMD25 can take anywhere between 5 and +15s on Samsung EMMCs and the current timeout is not enough. Increase the timeout by 2x to accommodate the long transfer times observed. Signed-off-by: Iulian Banaga Acked-by: Jimmy Durand Wesolowski Reviewed-by: Peng Fan Signed-off-by: Peng Fan --- drivers/mmc/mmc_write.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index 90fcf2679bb..928c05872ca 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -155,6 +155,7 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start, struct mmc_cmd cmd; struct mmc_data data; int timeout_ms = 1000; + int err; if ((start + blkcnt) > mmc_get_blk_desc(mmc)->lba) { printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n", @@ -181,9 +182,13 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start, data.blocksize = mmc->write_bl_len; data.flags = MMC_DATA_WRITE; - if (mmc_send_cmd(mmc, &cmd, &data)) { + err = mmc_send_cmd(mmc, &cmd, &data); + if (err) { printf("mmc write failed\n"); - return 0; + /* + * Don't return 0 here since the emmc will still be in data + * transfer mode continue to send the STOP_TRANSMISSION command + */ } /* SPI multiblock writes terminate using a special @@ -203,6 +208,9 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start, if (mmc_poll_for_busy(mmc, timeout_ms)) return 0; + if (err) + return 0; + return blkcnt; }