[PATCH 3/9] mmc: dw_mmc: properly address command completion in dwmci_control_clken()
Peng Fan
peng.fan at oss.nxp.com
Wed Oct 22 09:56:49 CEST 2025
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 at 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
>
More information about the U-Boot
mailing list