* [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver
@ 2025-10-17 15:24 Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 1/9] mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios() Kaustabh Chakraborty
` (9 more replies)
0 siblings, 10 replies; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
This patch series aims to add support for eMMC and SD-Card in Exynos
7870 devices. This brings changes to the core DW-MMC code, and the
Exynos-specific driver as well, introducing HS and UHS mode support,
and changes in SD init sequences.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
Kaustabh Chakraborty (9):
mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios()
mmc: dw_mmc: do not skip dwmci_setup_bus() for same non-zero clock frequency
mmc: dw_mmc: properly address command completion in dwmci_control_clken()
mmc: dw_mmc: add voltage switch command flag
mmc: dw_mmc: return error for invalid voltage setting
mmc: enable/disable VQMMC regulator only during MMC power cycle
mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes
mmc: exynos_dw_mmc: add support for SD UHS mode
mmc: exynos_dw_mmc: add compatible for exynos7870-dw-mshc-smu
drivers/mmc/dw_mmc.c | 50 ++++++++--------
drivers/mmc/exynos_dw_mmc.c | 135 +++++++++++++++++++++++++++++++++++++-------
drivers/mmc/mmc.c | 20 +++++++
include/dwmmc.h | 7 +++
4 files changed, 169 insertions(+), 43 deletions(-)
---
base-commit: 582a04763aa80738c1c8ac60c47d1a5159a42833
change-id: 20251014-mmc-dw-exynos7870-91e92a9f6a8a
Best regards,
--
Kaustabh Chakraborty <kauschluss@disroot.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/9] mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios()
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-22 8:15 ` Peng Fan
2025-10-17 15:24 ` [PATCH 2/9] mmc: dw_mmc: do not skip dwmci_setup_bus() for same non-zero clock frequency Kaustabh Chakraborty
` (8 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
These commands are required by struct dm_mmc_ops. Any platform specific
driver may use some or all of the functions in their own ops. Make them
accessible by moving the prototype to the dwmmc.h header.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/dw_mmc.c | 6 +++---
include/dwmmc.h | 3 +++
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index a51494380ce0119f6d7128c3bc74a2edb87ce11e..c6a18a5427ac64cc74a0a95f9780156b52beeee5 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -482,8 +482,8 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd,
}
#ifdef CONFIG_DM_MMC
-static int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
- struct mmc_data *data)
+int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
{
struct mmc *mmc = mmc_get_mmc_dev(dev);
#else
@@ -585,7 +585,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
}
#ifdef CONFIG_DM_MMC
-static int dwmci_set_ios(struct udevice *dev)
+int dwmci_set_ios(struct udevice *dev)
{
struct mmc *mmc = mmc_get_mmc_dev(dev);
#else
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 87ca127cd6cd53a9a68f77f0981356e77d88ab07..639a2d28e7860f2ceb09955ee11550e406fd1bd2 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -334,6 +334,9 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
#ifdef CONFIG_DM_MMC
/* Export the operations to drivers */
int dwmci_probe(struct udevice *dev);
+int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data);
+int dwmci_set_ios(struct udevice *dev);
extern const struct dm_mmc_ops dm_dwmci_ops;
#endif
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/9] mmc: dw_mmc: do not skip dwmci_setup_bus() for same non-zero clock frequency
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 1/9] mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios() Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-22 8:15 ` Peng Fan
2025-10-17 15:24 ` [PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken() Kaustabh Chakraborty
` (7 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
In dwmci_setup_bus(), if the requested frequency is equal to the current
frequency, the function is returned, assuming no changes are required in
associated registers.
On certain SD cards, skipping in such situations may result in a timeout
errors during MMC initialization. Due to the lack of documentation, the
cause is unknown, but removing said check seems to fix the issue.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/dw_mmc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index c6a18a5427ac64cc74a0a95f9780156b52beeee5..130a5bb57f3cddc50b3cd0df2f40981de680e852 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -554,7 +554,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
unsigned long sclk;
int ret;
- if (freq == host->clock || freq == 0)
+ if (!freq)
return 0;
/*
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken()
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 1/9] mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios() Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 2/9] mmc: dw_mmc: do not skip dwmci_setup_bus() for same non-zero clock frequency Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-22 7:56 ` Peng Fan
2025-10-17 15:24 ` [PATCH 4/9] mmc: dw_mmc: add voltage switch command flag Kaustabh Chakraborty
` (6 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
The current implementation polls for the DWMCI_CMD register, for the
DWMCI_CMD_START bit to turn off, which indicates that the command has
been completed. The problem with this approach is that it doesn't
address the DWMCI_INTMSK_CDONE bit in the interrupt register,
DWMCI_RINTSTS. As a result, subsequent commands result in timeout errors.
Re-implement the waiting logic by polling for said interrupt status bit
and setting it low if raised.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/dw_mmc.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 130a5bb57f3cddc50b3cd0df2f40981de680e852..1aa992c352c3f11ccdd1c02745fa988646952261 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -507,20 +507,21 @@ static int dwmci_control_clken(struct dwmci_host *host, bool on)
{
const u32 val = on ? DWMCI_CLKEN_ENABLE | DWMCI_CLKEN_LOW_PWR : 0;
const u32 cmd_only_clk = DWMCI_CMD_PRV_DAT_WAIT | DWMCI_CMD_UPD_CLK;
- int timeout = 10000;
- u32 status;
+ int i, timeout = 10000;
+ u32 mask;
dwmci_writel(host, DWMCI_CLKENA, val);
/* Inform CIU */
dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_START | cmd_only_clk);
- do {
- status = dwmci_readl(host, DWMCI_CMD);
- if (timeout-- < 0) {
- debug("%s: Timeout!\n", __func__);
- return -ETIMEDOUT;
+
+ for (i = 0; i < timeout; i++) {
+ mask = dwmci_readl(host, DWMCI_RINTSTS);
+ if (mask & DWMCI_INTMSK_CDONE) {
+ dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_CDONE);
+ break;
}
- } while (status & DWMCI_CMD_START);
+ }
return 0;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 4/9] mmc: dw_mmc: add voltage switch command flag
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
` (2 preceding siblings ...)
2025-10-17 15:24 ` [PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken() Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-22 8:14 ` Peng Fan
2025-10-17 15:24 ` [PATCH 5/9] mmc: dw_mmc: return error for invalid voltage setting Kaustabh Chakraborty
` (5 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
During a voltage switch command (CMD11, opcode: SD_CMD_SWITCH_UHS18V),
certain hosts tend to stop responding to subsequent commands. This is
addressed by introducing an additional command flag,
DWMCI_CMD_VOLT_SWITCH.
The associated interrupt bit is defined as DWMCI_INTMSK_VOLTSW. This is
set high when a voltage switch is issued, this needs to be waited for
and set to low. Implement the same in the timeout loop. Do note that
since DWMCI_INTMSK_VOLTSW shares the same bit as DWMCI_INTMSK_HTO (bit
10), the interrupt bit needs to be polled for only if the volt switch
command is issued.
DWMCI_CMD_VOLT_SWITCH also needs to be set for subsequent clken commands
after the volt switch. To ensure this, add a boolean member in the host
private struct (herein named volt_switching), which informs if the last
command issued was for volt switching or not.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/dw_mmc.c | 15 +++++++++++++--
include/dwmmc.h | 4 ++++
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 1aa992c352c3f11ccdd1c02745fa988646952261..94b6641c44c39e67aac453c027d519c0e1580de6 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -419,6 +419,10 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd,
if (cmd->resp_type & MMC_RSP_CRC)
flags |= DWMCI_CMD_CHECK_CRC;
+ host->volt_switching = (cmd->cmdidx == SD_CMD_SWITCH_UHS18V);
+ if (host->volt_switching)
+ flags |= DWMCI_CMD_VOLT_SWITCH;
+
flags |= cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG;
debug("Sending CMD%d\n", cmd->cmdidx);
@@ -427,6 +431,10 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd,
for (i = 0; i < retry; i++) {
mask = dwmci_readl(host, DWMCI_RINTSTS);
+ if (host->volt_switching && (mask & DWMCI_INTMSK_VOLTSW)) {
+ dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_VOLTSW);
+ break;
+ }
if (mask & DWMCI_INTMSK_CDONE) {
if (!data)
dwmci_writel(host, DWMCI_RINTSTS, mask);
@@ -508,12 +516,15 @@ static int dwmci_control_clken(struct dwmci_host *host, bool on)
const u32 val = on ? DWMCI_CLKEN_ENABLE | DWMCI_CLKEN_LOW_PWR : 0;
const u32 cmd_only_clk = DWMCI_CMD_PRV_DAT_WAIT | DWMCI_CMD_UPD_CLK;
int i, timeout = 10000;
- u32 mask;
+ u32 flags, mask;
dwmci_writel(host, DWMCI_CLKENA, val);
/* Inform CIU */
- dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_START | cmd_only_clk);
+ flags = DWMCI_CMD_START | cmd_only_clk;
+ if (host->volt_switching)
+ flags |= DWMCI_CMD_VOLT_SWITCH;
+ dwmci_writel(host, DWMCI_CMD, flags);
for (i = 0; i < timeout; i++) {
mask = dwmci_readl(host, DWMCI_RINTSTS);
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 639a2d28e7860f2ceb09955ee11550e406fd1bd2..47e3220985e900050d9db9d80e0d45efe6c2e545 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -72,6 +72,7 @@
#define DWMCI_INTMSK_RTO BIT(8)
#define DWMCI_INTMSK_DRTO BIT(9)
#define DWMCI_INTMSK_HTO BIT(10)
+#define DWMCI_INTMSK_VOLTSW BIT(10) /* overlap! */
#define DWMCI_INTMSK_FRUN BIT(11)
#define DWMCI_INTMSK_HLE BIT(12)
#define DWMCI_INTMSK_SBE BIT(13)
@@ -104,6 +105,7 @@
#define DWMCI_CMD_ABORT_STOP BIT(14)
#define DWMCI_CMD_PRV_DAT_WAIT BIT(13)
#define DWMCI_CMD_UPD_CLK BIT(21)
+#define DWMCI_CMD_VOLT_SWITCH BIT(28)
#define DWMCI_CMD_USE_HOLD_REG BIT(29)
#define DWMCI_CMD_START BIT(31)
@@ -190,6 +192,7 @@ struct dwmci_idmac_regs {
* @cfg: Internal MMC configuration, for !CONFIG_BLK cases
* @fifo_mode: Use FIFO mode (not DMA) to read and write data
* @dma_64bit_address: Whether DMA supports 64-bit address mode or not
+ * @volt_switching: Whether SD voltage switching is in process or not
* @regs: Registers that can vary for different DW MMC block versions
*/
struct dwmci_host {
@@ -229,6 +232,7 @@ struct dwmci_host {
bool fifo_mode;
bool dma_64bit_address;
+ bool volt_switching;
const struct dwmci_idmac_regs *regs;
};
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 5/9] mmc: dw_mmc: return error for invalid voltage setting
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
` (3 preceding siblings ...)
2025-10-17 15:24 ` [PATCH 4/9] mmc: dw_mmc: add voltage switch command flag Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-22 8:15 ` Peng Fan
2025-10-17 15:24 ` [PATCH 6/9] mmc: enable/disable VQMMC regulator only during MMC power cycle Kaustabh Chakraborty
` (4 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
In certain cases, the VQMMC regulator may not support certain voltages.
For instance, a VQMMC regulator which supports only up to 2.7V will not
accept 3.3V as an argument. This is unaccounted for, and thus the driver
incorrectly assumes that the voltage is set successfully.
Fetch the return value in a variable and return if it's non-zero.
(-ENOSYS is exempted as it implies that the voltage adjustment
functionality as a whole isn't supported).
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/dw_mmc.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 94b6641c44c39e67aac453c027d519c0e1580de6..9b143f9931e69531a53caa0196399e9392ddd348 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -649,9 +649,11 @@ static int dwmci_set_ios(struct mmc *mmc)
return ret;
if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
- regulator_set_value(mmc->vqmmc_supply, 1800000);
+ ret = regulator_set_value(mmc->vqmmc_supply, 1800000);
else
- regulator_set_value(mmc->vqmmc_supply, 3300000);
+ ret = regulator_set_value(mmc->vqmmc_supply, 3300000);
+ if (ret && ret != -ENOSYS)
+ return ret;
ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply, true);
if (ret)
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 6/9] mmc: enable/disable VQMMC regulator only during MMC power cycle
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
` (4 preceding siblings ...)
2025-10-17 15:24 ` [PATCH 5/9] mmc: dw_mmc: return error for invalid voltage setting Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes Kaustabh Chakraborty
` (3 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
Disrupting the regulator voltage during ios configuration messes with
the MMC initialization sequence. Move the VQMMC regulator enable/disable
functions to the MMC power cycle function, similar to how its done for
the VMMC regulator.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/dw_mmc.c | 8 --------
drivers/mmc/mmc.c | 20 ++++++++++++++++++++
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 9b143f9931e69531a53caa0196399e9392ddd348..f3c0cc5cd8e5045a870b5d5d2952da21bfba7e4d 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -644,20 +644,12 @@ static int dwmci_set_ios(struct mmc *mmc)
if (mmc->vqmmc_supply) {
int ret;
- ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply, false);
- if (ret)
- return ret;
-
if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
ret = regulator_set_value(mmc->vqmmc_supply, 1800000);
else
ret = regulator_set_value(mmc->vqmmc_supply, 3300000);
if (ret && ret != -ENOSYS)
return ret;
-
- ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply, true);
- if (ret)
- return ret;
}
#endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index b1cfa3cd7c22fac07fa16fac1cdb9500d2470a50..55dd021897c98b3af0ffddc9f64c035bf2e6484b 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -2844,6 +2844,16 @@ static int mmc_power_on(struct mmc *mmc)
return ret;
}
}
+
+ if (mmc->vqmmc_supply) {
+ int ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply,
+ true);
+
+ if (ret && ret != -ENOSYS) {
+ printf("Error enabling VQMMC supply : %d\n", ret);
+ return ret;
+ }
+ }
#endif
return 0;
}
@@ -2861,6 +2871,16 @@ static int mmc_power_off(struct mmc *mmc)
return ret;
}
}
+
+ if (mmc->vqmmc_supply) {
+ int ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply,
+ false);
+
+ if (ret && ret != -ENOSYS) {
+ pr_debug("Error disabling VQMMC supply : %d\n", ret);
+ return ret;
+ }
+ }
#endif
return 0;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
` (5 preceding siblings ...)
2025-10-17 15:24 ` [PATCH 6/9] mmc: enable/disable VQMMC regulator only during MMC power cycle Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-22 8:18 ` Peng Fan
2025-10-23 10:46 ` Tanmay Kathpalia
2025-10-17 15:24 ` [PATCH 8/9] mmc: exynos_dw_mmc: add support for SD UHS mode Kaustabh Chakraborty
` (2 subsequent siblings)
9 siblings, 2 replies; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
MMC HS200 and HS400 modes are already supported by the Exynos DW-MMC
driver in mainline Linux. Using that as reference, add support in the
U-Boot driver.
The maximum frequency was capped to 50000000, increase it to 200000000,
which is the required frequency for HS200/HS400. Moreover, add
MMC_MODE_HS200 and MMC_MODE_HS400 to host capailities. These changes
allow both host and card to recognize support for HS200/HS400.
This change also includes a new ops function, namely execute_tuning.
Implementing it would mean that we can no longer rely on the default ops
provided by dw_mmc.c, thus a new ops instance is created with proper
fields. The execute_tuning function is modeled after the one available
in the Linux driver.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/exynos_dw_mmc.c | 88 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 83 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index 12e37cb4b7884c5cdac0303245c93988d034459a..8311036109837d710ec141137684cd4f45ae449f 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -18,13 +18,18 @@
#include <linux/printk.h>
#define DWMMC_MAX_CH_NUM 4
-#define DWMMC_MAX_FREQ 52000000
+#define DWMMC_MAX_FREQ 200000000
#define DWMMC_MIN_FREQ 400000
#define DWMMC_MMC0_SDR_TIMING_VAL 0x03030001
#define DWMMC_MMC2_SDR_TIMING_VAL 0x03020001
#define EXYNOS4412_FIXED_CIU_CLK_DIV 4
+/* CLKSEL register defines */
+#define CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0)
+#define CLKSEL_UP_SAMPLE(x, y) (((x) & ~CLKSEL_CCLK_SAMPLE(7)) |\
+ CLKSEL_CCLK_SAMPLE(y))
+
/* Quirks */
#define DWMCI_QUIRK_DISABLE_SMU BIT(0)
@@ -166,8 +171,9 @@ static unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
u8 clk_div;
int err;
- /* Should be double rate for DDR mode */
- if (host->mmc->selected_mode == MMC_DDR_52 && host->mmc->bus_width == 8)
+ /* Should be double rate for DDR or HS mode */
+ if ((host->mmc->selected_mode == MMC_DDR_52 && host->mmc->bus_width == 8) ||
+ host->mmc->selected_mode == MMC_HS_400)
freq *= 2;
clk_div = exynos_dwmmc_get_ciu_div(host);
@@ -282,6 +288,72 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev)
return 0;
}
+static int exynos_dwmmc_get_best_clksmpl(u8 candidates)
+{
+ u8 i;
+
+ for (i = 0; i < 8; i++) {
+ candidates = (candidates >> 1) | (candidates << 7); /* ror */
+ if ((candidates & 0xc7) == 0xc7)
+ return i;
+ }
+
+ for (i = 0; i < 8; i++) {
+ candidates = (candidates >> 1) | (candidates << 7); /* ror */
+ if ((candidates & 0x83) == 0x83)
+ return i;
+ }
+
+ /*
+ * If no valid clock sample values are found, use the first
+ * canditate bit for clock sample value.
+ */
+ for (i = 0; i < 8; i++) {
+ candidates = (candidates >> 1) | (candidates << 7); /* ror */
+ if ((candidates & 0x1) == 0x1)
+ return i;
+ }
+
+ return -EIO;
+}
+
+static int exynos_dwmmc_execute_tuning(struct udevice *dev, u32 opcode)
+{
+ struct dwmci_exynos_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+ u8 start_smpl, smpl, candidates = 0;
+ u32 clksel;
+ int ret;
+
+ clksel = dwmci_readl(host, priv->chip->clksel);
+ start_smpl = CLKSEL_CCLK_SAMPLE(clksel);
+
+ do {
+ dwmci_writel(host, DWMCI_TMOUT, ~0);
+
+ /* move to the next clksmpl */
+ smpl = (clksel + 1) & 0x7;
+ clksel = CLKSEL_UP_SAMPLE(clksel, smpl);
+ dwmci_writel(host, priv->chip->clksel, clksel);
+
+ if (!mmc_send_tuning(mmc, opcode))
+ candidates |= (1 << smpl);
+
+ } while (start_smpl != smpl);
+
+ ret = exynos_dwmmc_get_best_clksmpl(candidates);
+ if (ret < 0) {
+ printf("DWMMC%d: No candidates for clksmpl\n", host->dev_index);
+ return ret;
+ }
+
+ dwmci_writel(host, priv->chip->clksel,
+ CLKSEL_UP_SAMPLE(clksel, ret));
+
+ return 0;
+}
+
static int exynos_dwmmc_probe(struct udevice *dev)
{
struct exynos_mmc_plat *plat = dev_get_plat(dev);
@@ -321,7 +393,7 @@ static int exynos_dwmmc_probe(struct udevice *dev)
host->name = dev->name;
host->board_init = exynos_dwmci_board_init;
- host->caps = MMC_MODE_DDR_52MHz;
+ host->caps = MMC_MODE_DDR_52MHz | MMC_MODE_HS200 | MMC_MODE_HS400;
host->clksel = exynos_dwmci_clksel;
host->get_mmc_clk = exynos_dwmci_get_clk;
@@ -388,6 +460,12 @@ static const struct udevice_id exynos_dwmmc_ids[] = {
{ }
};
+struct dm_mmc_ops exynos_dwmmc_ops = {
+ .send_cmd = dwmci_send_cmd,
+ .set_ios = dwmci_set_ios,
+ .execute_tuning = exynos_dwmmc_execute_tuning,
+};
+
U_BOOT_DRIVER(exynos_dwmmc_drv) = {
.name = "exynos_dwmmc",
.id = UCLASS_MMC,
@@ -395,7 +473,7 @@ U_BOOT_DRIVER(exynos_dwmmc_drv) = {
.of_to_plat = exynos_dwmmc_of_to_plat,
.bind = exynos_dwmmc_bind,
.probe = exynos_dwmmc_probe,
- .ops = &dm_dwmci_ops,
+ .ops = &exynos_dwmmc_ops,
.priv_auto = sizeof(struct dwmci_exynos_priv_data),
.plat_auto = sizeof(struct exynos_mmc_plat),
};
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 8/9] mmc: exynos_dw_mmc: add support for SD UHS mode
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
` (6 preceding siblings ...)
2025-10-17 15:24 ` [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-22 8:19 ` Peng Fan
2025-10-17 15:24 ` [PATCH 9/9] mmc: exynos_dw_mmc: add compatible for exynos7870-dw-mshc-smu Kaustabh Chakraborty
2025-10-23 8:46 ` [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Peng Fan (OSS)
9 siblings, 1 reply; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
SD UHS mode is already supported by the Exynos DW-MMC driver in mainline
Linux. Using that as reference, add support in the U-Boot driver.
The maximum frequency was capped to 200000000, increase it to 208000000,
which is the required frequency for UHS_SDR104, which has the highest
frequency of all UHS modes. Moreover, add UHS_CAPS to host capailities.
These changes allow both host and card to recognize support for all UHS
modes.
SDR104, SDR50, and DDR50 have their own CLKSEL timing values, which
requires the CIU div value to be set in bits 18:16. Move the function
exynos_dwmci_clksel() below exynos_dwmmc_get_ciu_div() so that the
latter is accessible from the former, and add cases for said timing
modes.
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/exynos_dw_mmc.c | 48 ++++++++++++++++++++++++++++-----------------
1 file changed, 30 insertions(+), 18 deletions(-)
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index 8311036109837d710ec141137684cd4f45ae449f..d436d33f53b36aadab3621a14e37ced71b23d96e 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -18,7 +18,7 @@
#include <linux/printk.h>
#define DWMMC_MAX_CH_NUM 4
-#define DWMMC_MAX_FREQ 200000000
+#define DWMMC_MAX_FREQ 208000000
#define DWMMC_MIN_FREQ 400000
#define DWMMC_MMC0_SDR_TIMING_VAL 0x03030001
#define DWMMC_MMC2_SDR_TIMING_VAL 0x03020001
@@ -126,22 +126,6 @@ static int exynos_dwmmc_set_sclk(struct dwmci_host *host, unsigned long rate)
return 0;
}
-/* Configure CLKSEL register with chosen timing values */
-static int exynos_dwmci_clksel(struct dwmci_host *host)
-{
- struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
- u32 timing;
-
- if (host->mmc->selected_mode == MMC_DDR_52)
- timing = priv->ddr_timing;
- else
- timing = priv->sdr_timing;
-
- dwmci_writel(host, priv->chip->clksel, timing);
-
- return 0;
-}
-
/**
* exynos_dwmmc_get_ciu_div - Get internal clock divider value
* @host: MMC controller object
@@ -165,6 +149,33 @@ static u8 exynos_dwmmc_get_ciu_div(struct dwmci_host *host)
& DWMCI_DIVRATIO_MASK) + 1;
}
+/* Configure CLKSEL register with chosen timing values */
+static int exynos_dwmci_clksel(struct dwmci_host *host)
+{
+ struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
+ u8 clk_div = exynos_dwmmc_get_ciu_div(host) - 1;
+ u32 timing;
+
+ switch (host->mmc->selected_mode) {
+ case MMC_DDR_52:
+ timing = priv->ddr_timing;
+ break;
+ case UHS_SDR104:
+ case UHS_SDR50:
+ timing = (priv->sdr_timing & 0xfff8ffff) | (clk_div << 16);
+ break;
+ case UHS_DDR50:
+ timing = (priv->ddr_timing & 0xfff8ffff) | (clk_div << 16);
+ break;
+ default:
+ timing = priv->sdr_timing;
+ }
+
+ dwmci_writel(host, priv->chip->clksel, timing);
+
+ return 0;
+}
+
static unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)
{
unsigned long sclk;
@@ -393,7 +404,8 @@ static int exynos_dwmmc_probe(struct udevice *dev)
host->name = dev->name;
host->board_init = exynos_dwmci_board_init;
- host->caps = MMC_MODE_DDR_52MHz | MMC_MODE_HS200 | MMC_MODE_HS400;
+ host->caps = MMC_MODE_DDR_52MHz | MMC_MODE_HS200 | MMC_MODE_HS400 |
+ UHS_CAPS;
host->clksel = exynos_dwmci_clksel;
host->get_mmc_clk = exynos_dwmci_get_clk;
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 9/9] mmc: exynos_dw_mmc: add compatible for exynos7870-dw-mshc-smu
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
` (7 preceding siblings ...)
2025-10-17 15:24 ` [PATCH 8/9] mmc: exynos_dw_mmc: add support for SD UHS mode Kaustabh Chakraborty
@ 2025-10-17 15:24 ` Kaustabh Chakraborty
2025-10-22 8:20 ` Peng Fan
2025-10-23 8:46 ` [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Peng Fan (OSS)
9 siblings, 1 reply; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-17 15:24 UTC (permalink / raw)
To: u-boot
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler, Kaustabh Chakraborty
Exynos7870 is documented in upstream dt-schema. Add it in the U-Boot
driver.
Note that here it seems that Exynos7 DW MMC is perfectly compatible with
Exynos7870 DW MMC. It's not always true, especially in SDIO cards where
data from a 64-bit FIFO is read in two 32-bit halves [1]. Since SDIO
isn't used or implemented here, it's oblivious. But upstream's schema
considers that quirk, so that compatible is followed.
Link: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7cbe799ac10f [1]
Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
---
drivers/mmc/exynos_dw_mmc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
index d436d33f53b36aadab3621a14e37ced71b23d96e..12d7411a72ef5cb80689bcb0ae1398f375ec9a5f 100644
--- a/drivers/mmc/exynos_dw_mmc.c
+++ b/drivers/mmc/exynos_dw_mmc.c
@@ -468,6 +468,9 @@ static const struct udevice_id exynos_dwmmc_ids[] = {
}, {
.compatible = "samsung,exynos7-dw-mshc-smu",
.data = (ulong)&exynos7_smu_drv_data,
+ }, {
+ .compatible = "samsung,exynos7870-dw-mshc-smu",
+ .data = (ulong)&exynos7_smu_drv_data,
},
{ }
};
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken()
2025-10-17 15:24 ` [PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken() Kaustabh Chakraborty
@ 2025-10-22 7:56 ` Peng Fan
2025-10-23 16:36 ` Kaustabh Chakraborty
0 siblings, 1 reply; 22+ messages in thread
From: Peng Fan @ 2025-10-22 7:56 UTC (permalink / raw)
To: Kaustabh Chakraborty
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
Hi Kaustabh,
On Fri, Oct 17, 2025 at 08:54:08PM +0530, Kaustabh Chakraborty wrote:
>The current implementation polls for the DWMCI_CMD register, for the
>DWMCI_CMD_START bit to turn off, which indicates that the command has
>been completed. The problem with this approach is that it doesn't
>address the DWMCI_INTMSK_CDONE bit in the interrupt register,
>DWMCI_RINTSTS. As a result, subsequent commands result in timeout errors.
This patch looks good to me, but I need a few more details to understand:
Do you mean that DWMCI_INTMSK_CDONE must be cleared before sending
out next cmd?
Per my guess, DWMCI_CMD_START will be cleared when CMD done from
controller perspective, but the card may not return back response.
DWMCI_INTMSK_CDONE means response done. But if there is some commands
does not have response, will DWMCI_INTMSK_CDONE still be set?
Please help clarify.
Thanks,
Peng
>
>Re-implement the waiting logic by polling for said interrupt status bit
>and setting it low if raised.
>
>Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
>---
> drivers/mmc/dw_mmc.c | 17 +++++++++--------
> 1 file changed, 9 insertions(+), 8 deletions(-)
>
>diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
>index 130a5bb57f3cddc50b3cd0df2f40981de680e852..1aa992c352c3f11ccdd1c02745fa988646952261 100644
>--- a/drivers/mmc/dw_mmc.c
>+++ b/drivers/mmc/dw_mmc.c
>@@ -507,20 +507,21 @@ static int dwmci_control_clken(struct dwmci_host *host, bool on)
> {
> const u32 val = on ? DWMCI_CLKEN_ENABLE | DWMCI_CLKEN_LOW_PWR : 0;
> const u32 cmd_only_clk = DWMCI_CMD_PRV_DAT_WAIT | DWMCI_CMD_UPD_CLK;
>- int timeout = 10000;
>- u32 status;
>+ int i, timeout = 10000;
>+ u32 mask;
>
> dwmci_writel(host, DWMCI_CLKENA, val);
>
> /* Inform CIU */
> dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_START | cmd_only_clk);
>- do {
>- status = dwmci_readl(host, DWMCI_CMD);
>- if (timeout-- < 0) {
>- debug("%s: Timeout!\n", __func__);
>- return -ETIMEDOUT;
>+
>+ for (i = 0; i < timeout; i++) {
>+ mask = dwmci_readl(host, DWMCI_RINTSTS);
>+ if (mask & DWMCI_INTMSK_CDONE) {
>+ dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_CDONE);
>+ break;
> }
>- } while (status & DWMCI_CMD_START);
>+ }
>
> return 0;
> }
>
>--
>2.51.0
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/9] mmc: dw_mmc: add voltage switch command flag
2025-10-17 15:24 ` [PATCH 4/9] mmc: dw_mmc: add voltage switch command flag Kaustabh Chakraborty
@ 2025-10-22 8:14 ` Peng Fan
2025-10-22 20:25 ` Kaustabh Chakraborty
0 siblings, 1 reply; 22+ messages in thread
From: Peng Fan @ 2025-10-22 8:14 UTC (permalink / raw)
To: Kaustabh Chakraborty
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
Hi Kaustabh,
On Fri, Oct 17, 2025 at 08:54:09PM +0530, Kaustabh Chakraborty wrote:
>During a voltage switch command (CMD11, opcode: SD_CMD_SWITCH_UHS18V),
>certain hosts tend to stop responding to subsequent commands. This is
>addressed by introducing an additional command flag,
>DWMCI_CMD_VOLT_SWITCH.
is there any errata or spec have this information public?
>
>The associated interrupt bit is defined as DWMCI_INTMSK_VOLTSW. This is
>set high when a voltage switch is issued, this needs to be waited for
>and set to low. Implement the same in the timeout loop. Do note that
>since DWMCI_INTMSK_VOLTSW shares the same bit as DWMCI_INTMSK_HTO (bit
>10), the interrupt bit needs to be polled for only if the volt switch
>command is issued.
>
>DWMCI_CMD_VOLT_SWITCH also needs to be set for subsequent clken commands
>after the volt switch. To ensure this, add a boolean member in the host
>private struct (herein named volt_switching), which informs if the last
>command issued was for volt switching or not.
>
>Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
>---
> drivers/mmc/dw_mmc.c | 15 +++++++++++++--
> include/dwmmc.h | 4 ++++
> 2 files changed, 17 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
>index 1aa992c352c3f11ccdd1c02745fa988646952261..94b6641c44c39e67aac453c027d519c0e1580de6 100644
>--- a/drivers/mmc/dw_mmc.c
>+++ b/drivers/mmc/dw_mmc.c
>@@ -419,6 +419,10 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd,
> if (cmd->resp_type & MMC_RSP_CRC)
> flags |= DWMCI_CMD_CHECK_CRC;
>
>+ host->volt_switching = (cmd->cmdidx == SD_CMD_SWITCH_UHS18V);
>+ if (host->volt_switching)
>+ flags |= DWMCI_CMD_VOLT_SWITCH;
>+
> flags |= cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG;
>
> debug("Sending CMD%d\n", cmd->cmdidx);
>@@ -427,6 +431,10 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd,
>
> for (i = 0; i < retry; i++) {
> mask = dwmci_readl(host, DWMCI_RINTSTS);
>+ if (host->volt_switching && (mask & DWMCI_INTMSK_VOLTSW)) {
>+ dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_VOLTSW);
>+ break;
>+ }
> if (mask & DWMCI_INTMSK_CDONE) {
> if (!data)
> dwmci_writel(host, DWMCI_RINTSTS, mask);
>@@ -508,12 +516,15 @@ static int dwmci_control_clken(struct dwmci_host *host, bool on)
> const u32 val = on ? DWMCI_CLKEN_ENABLE | DWMCI_CLKEN_LOW_PWR : 0;
> const u32 cmd_only_clk = DWMCI_CMD_PRV_DAT_WAIT | DWMCI_CMD_UPD_CLK;
> int i, timeout = 10000;
>- u32 mask;
>+ u32 flags, mask;
>
> dwmci_writel(host, DWMCI_CLKENA, val);
>
> /* Inform CIU */
>- dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_START | cmd_only_clk);
>+ flags = DWMCI_CMD_START | cmd_only_clk;
>+ if (host->volt_switching)
>+ flags |= DWMCI_CMD_VOLT_SWITCH;
>+ dwmci_writel(host, DWMCI_CMD, flags);
>
> for (i = 0; i < timeout; i++) {
> mask = dwmci_readl(host, DWMCI_RINTSTS);
>diff --git a/include/dwmmc.h b/include/dwmmc.h
>index 639a2d28e7860f2ceb09955ee11550e406fd1bd2..47e3220985e900050d9db9d80e0d45efe6c2e545 100644
>--- a/include/dwmmc.h
>+++ b/include/dwmmc.h
>@@ -72,6 +72,7 @@
> #define DWMCI_INTMSK_RTO BIT(8)
> #define DWMCI_INTMSK_DRTO BIT(9)
> #define DWMCI_INTMSK_HTO BIT(10)
>+#define DWMCI_INTMSK_VOLTSW BIT(10) /* overlap! */
> #define DWMCI_INTMSK_FRUN BIT(11)
> #define DWMCI_INTMSK_HLE BIT(12)
> #define DWMCI_INTMSK_SBE BIT(13)
>@@ -104,6 +105,7 @@
> #define DWMCI_CMD_ABORT_STOP BIT(14)
> #define DWMCI_CMD_PRV_DAT_WAIT BIT(13)
> #define DWMCI_CMD_UPD_CLK BIT(21)
>+#define DWMCI_CMD_VOLT_SWITCH BIT(28)
> #define DWMCI_CMD_USE_HOLD_REG BIT(29)
> #define DWMCI_CMD_START BIT(31)
>
>@@ -190,6 +192,7 @@ struct dwmci_idmac_regs {
> * @cfg: Internal MMC configuration, for !CONFIG_BLK cases
> * @fifo_mode: Use FIFO mode (not DMA) to read and write data
> * @dma_64bit_address: Whether DMA supports 64-bit address mode or not
>+ * @volt_switching: Whether SD voltage switching is in process or not
Since volt_switching y means in process, I not see it is cleared when it is
not needed. Is this expected?
Thanks,
Peng
> * @regs: Registers that can vary for different DW MMC block versions
> */
> struct dwmci_host {
>@@ -229,6 +232,7 @@ struct dwmci_host {
>
> bool fifo_mode;
> bool dma_64bit_address;
>+ bool volt_switching;
> const struct dwmci_idmac_regs *regs;
> };
>
>
>--
>2.51.0
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/9] mmc: dw_mmc: return error for invalid voltage setting
2025-10-17 15:24 ` [PATCH 5/9] mmc: dw_mmc: return error for invalid voltage setting Kaustabh Chakraborty
@ 2025-10-22 8:15 ` Peng Fan
0 siblings, 0 replies; 22+ messages in thread
From: Peng Fan @ 2025-10-22 8:15 UTC (permalink / raw)
To: Kaustabh Chakraborty
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
On Fri, Oct 17, 2025 at 08:54:10PM +0530, Kaustabh Chakraborty wrote:
>In certain cases, the VQMMC regulator may not support certain voltages.
>For instance, a VQMMC regulator which supports only up to 2.7V will not
>accept 3.3V as an argument. This is unaccounted for, and thus the driver
>incorrectly assumes that the voltage is set successfully.
>
>Fetch the return value in a variable and return if it's non-zero.
>(-ENOSYS is exempted as it implies that the voltage adjustment
>functionality as a whole isn't supported).
>
>Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/9] mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios()
2025-10-17 15:24 ` [PATCH 1/9] mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios() Kaustabh Chakraborty
@ 2025-10-22 8:15 ` Peng Fan
0 siblings, 0 replies; 22+ messages in thread
From: Peng Fan @ 2025-10-22 8:15 UTC (permalink / raw)
To: Kaustabh Chakraborty
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
On Fri, Oct 17, 2025 at 08:54:06PM +0530, Kaustabh Chakraborty wrote:
>These commands are required by struct dm_mmc_ops. Any platform specific
>driver may use some or all of the functions in their own ops. Make them
>accessible by moving the prototype to the dwmmc.h header.
>
>Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/9] mmc: dw_mmc: do not skip dwmci_setup_bus() for same non-zero clock frequency
2025-10-17 15:24 ` [PATCH 2/9] mmc: dw_mmc: do not skip dwmci_setup_bus() for same non-zero clock frequency Kaustabh Chakraborty
@ 2025-10-22 8:15 ` Peng Fan
0 siblings, 0 replies; 22+ messages in thread
From: Peng Fan @ 2025-10-22 8:15 UTC (permalink / raw)
To: Kaustabh Chakraborty
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
On Fri, Oct 17, 2025 at 08:54:07PM +0530, Kaustabh Chakraborty wrote:
>In dwmci_setup_bus(), if the requested frequency is equal to the current
>frequency, the function is returned, assuming no changes are required in
>associated registers.
>
>On certain SD cards, skipping in such situations may result in a timeout
>errors during MMC initialization. Due to the lack of documentation, the
>cause is unknown, but removing said check seems to fix the issue.
>
>Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes
2025-10-17 15:24 ` [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes Kaustabh Chakraborty
@ 2025-10-22 8:18 ` Peng Fan
2025-10-23 10:46 ` Tanmay Kathpalia
1 sibling, 0 replies; 22+ messages in thread
From: Peng Fan @ 2025-10-22 8:18 UTC (permalink / raw)
To: Kaustabh Chakraborty
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
On Fri, Oct 17, 2025 at 08:54:12PM +0530, Kaustabh Chakraborty wrote:
>MMC HS200 and HS400 modes are already supported by the Exynos DW-MMC
>driver in mainline Linux. Using that as reference, add support in the
>U-Boot driver.
>
>The maximum frequency was capped to 50000000, increase it to 200000000,
>which is the required frequency for HS200/HS400. Moreover, add
>MMC_MODE_HS200 and MMC_MODE_HS400 to host capailities. These changes
>allow both host and card to recognize support for HS200/HS400.
>
>This change also includes a new ops function, namely execute_tuning.
>Implementing it would mean that we can no longer rely on the default ops
>provided by dw_mmc.c, thus a new ops instance is created with proper
>fields. The execute_tuning function is modeled after the one available
>in the Linux driver.
>
>Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 8/9] mmc: exynos_dw_mmc: add support for SD UHS mode
2025-10-17 15:24 ` [PATCH 8/9] mmc: exynos_dw_mmc: add support for SD UHS mode Kaustabh Chakraborty
@ 2025-10-22 8:19 ` Peng Fan
0 siblings, 0 replies; 22+ messages in thread
From: Peng Fan @ 2025-10-22 8:19 UTC (permalink / raw)
To: Kaustabh Chakraborty
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
On Fri, Oct 17, 2025 at 08:54:13PM +0530, Kaustabh Chakraborty wrote:
>SD UHS mode is already supported by the Exynos DW-MMC driver in mainline
>Linux. Using that as reference, add support in the U-Boot driver.
>
>The maximum frequency was capped to 200000000, increase it to 208000000,
>which is the required frequency for UHS_SDR104, which has the highest
>frequency of all UHS modes. Moreover, add UHS_CAPS to host capailities.
>These changes allow both host and card to recognize support for all UHS
>modes.
>
>SDR104, SDR50, and DDR50 have their own CLKSEL timing values, which
>requires the CIU div value to be set in bits 18:16. Move the function
>exynos_dwmci_clksel() below exynos_dwmmc_get_ciu_div() so that the
>latter is accessible from the former, and add cases for said timing
>modes.
>
>Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 9/9] mmc: exynos_dw_mmc: add compatible for exynos7870-dw-mshc-smu
2025-10-17 15:24 ` [PATCH 9/9] mmc: exynos_dw_mmc: add compatible for exynos7870-dw-mshc-smu Kaustabh Chakraborty
@ 2025-10-22 8:20 ` Peng Fan
0 siblings, 0 replies; 22+ messages in thread
From: Peng Fan @ 2025-10-22 8:20 UTC (permalink / raw)
To: Kaustabh Chakraborty
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
On Fri, Oct 17, 2025 at 08:54:14PM +0530, Kaustabh Chakraborty wrote:
>Exynos7870 is documented in upstream dt-schema. Add it in the U-Boot
>driver.
>
>Note that here it seems that Exynos7 DW MMC is perfectly compatible with
>Exynos7870 DW MMC. It's not always true, especially in SDIO cards where
>data from a 64-bit FIFO is read in two 32-bit halves [1]. Since SDIO
>isn't used or implemented here, it's oblivious. But upstream's schema
>considers that quirk, so that compatible is followed.
>
>Link: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7cbe799ac10f [1]
>Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/9] mmc: dw_mmc: add voltage switch command flag
2025-10-22 8:14 ` Peng Fan
@ 2025-10-22 20:25 ` Kaustabh Chakraborty
0 siblings, 0 replies; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-22 20:25 UTC (permalink / raw)
To: Peng Fan
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
On 2025-10-22 08:14, Peng Fan wrote:
> Hi Kaustabh,
>
> On Fri, Oct 17, 2025 at 08:54:09PM +0530, Kaustabh Chakraborty wrote:
>> During a voltage switch command (CMD11, opcode: SD_CMD_SWITCH_UHS18V),
>> certain hosts tend to stop responding to subsequent commands. This is
>> addressed by introducing an additional command flag,
>> DWMCI_CMD_VOLT_SWITCH.
>
> is there any errata or spec have this information public?
I'm not aware of any. However, this behavior is found in the Linux
kernel
driver. See commit 0173055842cd1 ("mmc: dw_mmc: Support voltage
changes").
The state tracking in the kernel is however much more complex.
>
>>
>> The associated interrupt bit is defined as DWMCI_INTMSK_VOLTSW. This
>> is
>> set high when a voltage switch is issued, this needs to be waited for
>> and set to low. Implement the same in the timeout loop. Do note that
>> since DWMCI_INTMSK_VOLTSW shares the same bit as DWMCI_INTMSK_HTO (bit
>> 10), the interrupt bit needs to be polled for only if the volt switch
>> command is issued.
>>
>> DWMCI_CMD_VOLT_SWITCH also needs to be set for subsequent clken
>> commands
>> after the volt switch. To ensure this, add a boolean member in the
>> host
>> private struct (herein named volt_switching), which informs if the
>> last
>> command issued was for volt switching or not.
>>
>> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
>> ---
>> drivers/mmc/dw_mmc.c | 15 +++++++++++++--
>> include/dwmmc.h | 4 ++++
>> 2 files changed, 17 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
>> index
>> 1aa992c352c3f11ccdd1c02745fa988646952261..94b6641c44c39e67aac453c027d519c0e1580de6
>> 100644
>> --- a/drivers/mmc/dw_mmc.c
>> +++ b/drivers/mmc/dw_mmc.c
>> @@ -419,6 +419,10 @@ static int dwmci_send_cmd_common(struct
>> dwmci_host *host, struct mmc_cmd *cmd,
>> if (cmd->resp_type & MMC_RSP_CRC)
>> flags |= DWMCI_CMD_CHECK_CRC;
>>
>> + host->volt_switching = (cmd->cmdidx == SD_CMD_SWITCH_UHS18V);
[1]
>> + if (host->volt_switching)
>> + flags |= DWMCI_CMD_VOLT_SWITCH;
>> +
>> flags |= cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG;
>>
>> debug("Sending CMD%d\n", cmd->cmdidx);
>> @@ -427,6 +431,10 @@ static int dwmci_send_cmd_common(struct
>> dwmci_host *host, struct mmc_cmd *cmd,
>>
>> for (i = 0; i < retry; i++) {
>> mask = dwmci_readl(host, DWMCI_RINTSTS);
>> + if (host->volt_switching && (mask & DWMCI_INTMSK_VOLTSW)) {
>> + dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_VOLTSW);
>> + break;
>> + }
>> if (mask & DWMCI_INTMSK_CDONE) {
>> if (!data)
>> dwmci_writel(host, DWMCI_RINTSTS, mask);
>> @@ -508,12 +516,15 @@ static int dwmci_control_clken(struct dwmci_host
>> *host, bool on)
>> const u32 val = on ? DWMCI_CLKEN_ENABLE | DWMCI_CLKEN_LOW_PWR : 0;
>> const u32 cmd_only_clk = DWMCI_CMD_PRV_DAT_WAIT | DWMCI_CMD_UPD_CLK;
>> int i, timeout = 10000;
>> - u32 mask;
>> + u32 flags, mask;
>>
>> dwmci_writel(host, DWMCI_CLKENA, val);
>>
>> /* Inform CIU */
>> - dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_START | cmd_only_clk);
>> + flags = DWMCI_CMD_START | cmd_only_clk;
>> + if (host->volt_switching)
>> + flags |= DWMCI_CMD_VOLT_SWITCH;
>> + dwmci_writel(host, DWMCI_CMD, flags);
>>
>> for (i = 0; i < timeout; i++) {
>> mask = dwmci_readl(host, DWMCI_RINTSTS);
>> diff --git a/include/dwmmc.h b/include/dwmmc.h
>> index
>> 639a2d28e7860f2ceb09955ee11550e406fd1bd2..47e3220985e900050d9db9d80e0d45efe6c2e545
>> 100644
>> --- a/include/dwmmc.h
>> +++ b/include/dwmmc.h
>> @@ -72,6 +72,7 @@
>> #define DWMCI_INTMSK_RTO BIT(8)
>> #define DWMCI_INTMSK_DRTO BIT(9)
>> #define DWMCI_INTMSK_HTO BIT(10)
>> +#define DWMCI_INTMSK_VOLTSW BIT(10) /* overlap! */
>> #define DWMCI_INTMSK_FRUN BIT(11)
>> #define DWMCI_INTMSK_HLE BIT(12)
>> #define DWMCI_INTMSK_SBE BIT(13)
>> @@ -104,6 +105,7 @@
>> #define DWMCI_CMD_ABORT_STOP BIT(14)
>> #define DWMCI_CMD_PRV_DAT_WAIT BIT(13)
>> #define DWMCI_CMD_UPD_CLK BIT(21)
>> +#define DWMCI_CMD_VOLT_SWITCH BIT(28)
>> #define DWMCI_CMD_USE_HOLD_REG BIT(29)
>> #define DWMCI_CMD_START BIT(31)
>>
>> @@ -190,6 +192,7 @@ struct dwmci_idmac_regs {
>> * @cfg: Internal MMC configuration, for !CONFIG_BLK cases
>> * @fifo_mode: Use FIFO mode (not DMA) to read and write data
>> * @dma_64bit_address: Whether DMA supports 64-bit address mode or not
>> + * @volt_switching: Whether SD voltage switching is in process or not
>
> Since volt_switching y means in process, I not see it is cleared when
> it is
> not needed. Is this expected?
See [1] marked above. Its enabled when SD_CMD_SWITCH_UHS18V is the
opcode,
disabled otherwise.
>
> Thanks,
> Peng
>
>> * @regs: Registers that can vary for different DW MMC block versions
>> */
>> struct dwmci_host {
>> @@ -229,6 +232,7 @@ struct dwmci_host {
>>
>> bool fifo_mode;
>> bool dma_64bit_address;
>> + bool volt_switching;
>> const struct dwmci_idmac_regs *regs;
>> };
>>
>>
>> --
>> 2.51.0
>>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
` (8 preceding siblings ...)
2025-10-17 15:24 ` [PATCH 9/9] mmc: exynos_dw_mmc: add compatible for exynos7870-dw-mshc-smu Kaustabh Chakraborty
@ 2025-10-23 8:46 ` Peng Fan (OSS)
9 siblings, 0 replies; 22+ messages in thread
From: Peng Fan (OSS) @ 2025-10-23 8:46 UTC (permalink / raw)
To: u-boot, Kaustabh Chakraborty
Cc: Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass, Jonas Karlman,
Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
From: Peng Fan <peng.fan@nxp.com>
On Fri, 17 Oct 2025 20:54:05 +0530, Kaustabh Chakraborty wrote:
> This patch series aims to add support for eMMC and SD-Card in Exynos
> 7870 devices. This brings changes to the core DW-MMC code, and the
> Exynos-specific driver as well, introducing HS and UHS mode support,
> and changes in SD init sequences.
>
>
Applied to mmc/next, thanks!
[1/9] mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios()
commit: ef3b16bb8e731c93bb6d50c57c6d315486936d91
[2/9] mmc: dw_mmc: do not skip dwmci_setup_bus() for same non-zero clock frequency
commit: 4a0f11d4bd9b01aef6244e234b0ac4f9cb39acc0
[3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken()
commit: 8153127fac1ddafebdaf58f14a76b3ee9362bc22
[4/9] mmc: dw_mmc: add voltage switch command flag
commit: 1e5db3b82828d1a32d247f339c9aa1d09d52d35e
[5/9] mmc: dw_mmc: return error for invalid voltage setting
commit: 8acf595bcd8e411936da0b12461d281c8d26805c
[6/9] mmc: enable/disable VQMMC regulator only during MMC power cycle
commit: 5f0d548db8a600c095ae8b19f4b9920dc18a3442
[7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes
commit: eda4bd29929c892706627937c88676972f992471
[8/9] mmc: exynos_dw_mmc: add support for SD UHS mode
commit: d9020897f6d06191f3c126b1988316ad479eb98a
[9/9] mmc: exynos_dw_mmc: add compatible for exynos7870-dw-mshc-smu
commit: 3cbc9f0e0af744db339375d7a103d366ea70cb20
Best regards,
--
Peng Fan <peng.fan@nxp.com>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes
2025-10-17 15:24 ` [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes Kaustabh Chakraborty
2025-10-22 8:18 ` Peng Fan
@ 2025-10-23 10:46 ` Tanmay Kathpalia
1 sibling, 0 replies; 22+ messages in thread
From: Tanmay Kathpalia @ 2025-10-23 10:46 UTC (permalink / raw)
To: u-boot; +Cc: kauschluss, peng.fan
Subject: Re: [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes
Hi Kaustabh,
The tuning functionality should be made conditional under:
#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING)
This will ensure the code compiles cleanly on configurations where tuning
support is not enabled.
Best Regards,
Tanmay Kathpalia
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken()
2025-10-22 7:56 ` Peng Fan
@ 2025-10-23 16:36 ` Kaustabh Chakraborty
0 siblings, 0 replies; 22+ messages in thread
From: Kaustabh Chakraborty @ 2025-10-23 16:36 UTC (permalink / raw)
To: Peng Fan
Cc: u-boot, Peng Fan, Jaehoon Chung, Tom Rini, Simon Glass,
Jonas Karlman, Marek Vasut, Bhimeswararao Matsa, Andrew Goodbody,
Jean-Jacques Hiblot, Ronald Wahl, Anand Moon, Sam Protsenko,
Henrik Grimler
On 2025-10-22 07:56, Peng Fan wrote:
> Hi Kaustabh,
> On Fri, Oct 17, 2025 at 08:54:08PM +0530, Kaustabh Chakraborty wrote:
>>The current implementation polls for the DWMCI_CMD register, for the
>>DWMCI_CMD_START bit to turn off, which indicates that the command has
>>been completed. The problem with this approach is that it doesn't
>>address the DWMCI_INTMSK_CDONE bit in the interrupt register,
>>DWMCI_RINTSTS. As a result, subsequent commands result in timeout errors.
>
> This patch looks good to me, but I need a few more details to understand:
>
> Do you mean that DWMCI_INTMSK_CDONE must be cleared before sending
> out next cmd?
>
> Per my guess, DWMCI_CMD_START will be cleared when CMD done from
> controller perspective, but the card may not return back response.
> DWMCI_INTMSK_CDONE means response done. But if there is some commands
> does not have response, will DWMCI_INTMSK_CDONE still be set?
>
> Please help clarify.
This was observed experimentally actually. In Linux this seems to trigger
an interrupt, and the respective subroutine does clear the interrupt.
>
> Thanks,
> Peng
>
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2025-10-23 21:41 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-17 15:24 [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 1/9] mmc: dw_mmc: export dwmci_send_cmd() and dwmci_set_ios() Kaustabh Chakraborty
2025-10-22 8:15 ` Peng Fan
2025-10-17 15:24 ` [PATCH 2/9] mmc: dw_mmc: do not skip dwmci_setup_bus() for same non-zero clock frequency Kaustabh Chakraborty
2025-10-22 8:15 ` Peng Fan
2025-10-17 15:24 ` [PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken() Kaustabh Chakraborty
2025-10-22 7:56 ` Peng Fan
2025-10-23 16:36 ` Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 4/9] mmc: dw_mmc: add voltage switch command flag Kaustabh Chakraborty
2025-10-22 8:14 ` Peng Fan
2025-10-22 20:25 ` Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 5/9] mmc: dw_mmc: return error for invalid voltage setting Kaustabh Chakraborty
2025-10-22 8:15 ` Peng Fan
2025-10-17 15:24 ` [PATCH 6/9] mmc: enable/disable VQMMC regulator only during MMC power cycle Kaustabh Chakraborty
2025-10-17 15:24 ` [PATCH 7/9] mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes Kaustabh Chakraborty
2025-10-22 8:18 ` Peng Fan
2025-10-23 10:46 ` Tanmay Kathpalia
2025-10-17 15:24 ` [PATCH 8/9] mmc: exynos_dw_mmc: add support for SD UHS mode Kaustabh Chakraborty
2025-10-22 8:19 ` Peng Fan
2025-10-17 15:24 ` [PATCH 9/9] mmc: exynos_dw_mmc: add compatible for exynos7870-dw-mshc-smu Kaustabh Chakraborty
2025-10-22 8:20 ` Peng Fan
2025-10-23 8:46 ` [PATCH 0/9] Support for Samsung Exynos 7870 DW-MMC device in driver Peng Fan (OSS)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox