Skip to contentSkip to conversation

mmc: dw-mmc: retry to send when inform ciu

PATCH In review Jaehoon Chung 2 participants 3 messages Jul 13, 2012 – Jul 15, 2012

Subsystems (2)
lore
Share & tools
lore

Jaehoon Chung

author maintainer
#0 lore raw

PATCH 1/1 mmc: dw-mmc: retry to send when inform ciu

As DesignWare spec, when inform ciu, waiting for clearing start_bit or HLE is set. In case of HLE, repeat the command.

Before the patch, repeat the below message.
mmc_host mmc0: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000) If this message is produced, repeat the send command during 10 times.

---
 drivers/mmc/host/dw_mmc.c |   39 +++++++++++++++++++++++++++++++--------
 1 files changed, 31 insertions(+), 8 deletions(-)
drivers/mmc/host/dw_mmc.c +31 -8
index 72dc3cd..bec1a67 100644
@@ -603,7 +603,7 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
 	}
 }
 
-static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
+static int mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 {
 	struct dw_mci *host = slot->host;
 	unsigned long timeout = jiffies + msecs_to_jiffies(500);
@@ -616,11 +616,37 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 	while (time_before(jiffies, timeout)) {
 		cmd_status = mci_readl(host, CMD);
 		if (!(cmd_status & SDMMC_CMD_START))
-			return;
+			return 0;
 	}
 	dev_err(&slot->mmc->class_dev,
 		"Timeout sending command (cmd %#x arg %#x status %#x)\n",
 		cmd, arg, cmd_status);
+
+	return -ETIMEDOUT;
+}
+
+static void dw_mci_inform_ciu(struct dw_mci_slot *slot)
+{
+	struct dw_mci *host = slot->host;
+	unsigned long retry = 10;
+	int ret;
+	u32 ctrl;
+
+	while (1) {
+		ret = mci_send_cmd(slot,
+		     SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+		if (!ret)
+			break;
+		ctrl = mci_readl(host, CTRL);
+		ctrl |= SDMMC_CTRL_RESET;
+		mci_writel(host, CTRL, ctrl);
+
+		if (retry-- == 0) {
+			dev_err(&slot->mmc->class_dev,"Timeout inform CIU\n");
+			break;
+		} else
+			dev_info(&slot->mmc->class_dev,"Retry send command\n");
+	}
 }
 
 static void dw_mci_setup_bus(struct dw_mci_slot *slot)
@@ -649,23 +675,20 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
 		mci_writel(host, CLKSRC, 0);
 
 		/* inform CIU */
-		mci_send_cmd(slot,
-			     SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+		dw_mci_inform_ciu(slot);
 
 		/* set clock to desired speed */
 		mci_writel(host, CLKDIV, div);
 
 		/* inform CIU */
-		mci_send_cmd(slot,
-			     SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+		dw_mci_inform_ciu(slot);
 
 		/* enable clock */
 		mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE |
 			   SDMMC_CLKEN_LOW_PWR) << slot->id));
 
 		/* inform CIU */
-		mci_send_cmd(slot,
-			     SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+		dw_mci_inform_ciu(slot);
 
 		host->current_speed = slot->clock;
 	}
#1 lore raw
Quoted 6 lines · Jaehoon Chung

As DesignWare spec, when inform ciu, waiting for clearing start_bit or HLE is set. In case of HLE, repeat the command.

Before the patch, repeat the below message.
mmc_host mmc0: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000) If this message is produced, repeat the send command during 10 times.

I dont understand what the above message. its not clear. can you please explain it

Quoted 36 lines
---
 drivers/mmc/host/dw_mmc.c |   39 +++++++++++++++++++++++++++++++--------
 1 files changed, 31 insertions(+), 8 deletions(-)
drivers/mmc/host/dw_mmc.c +8 -2
index 72dc3cd..bec1a67 100644
@@ -603,7 +603,7 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
        }
 }
 
-static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
+static int mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 {
        struct dw_mci *host = slot->host;
        unsigned long timeout = jiffies + msecs_to_jiffies(500);
@@ -616,11 +616,37 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
        while (time_before(jiffies, timeout)) {
                cmd_status = mci_readl(host, CMD);
                if (!(cmd_status & SDMMC_CMD_START))
-                       return;
+                       return 0;
        }
        dev_err(&slot->mmc->class_dev,
                "Timeout sending command (cmd %#x arg %#x status %#x)\n",
                cmd, arg, cmd_status);
+
+       return -ETIMEDOUT;
+}
+
+static void dw_mci_inform_ciu(struct dw_mci_slot *slot)
+{

drivers/mmc/host/dw_mmc.c static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg) · line 639

Quoted 10 lines
drivers/mmc/host/dw_mmc.c +10 -0
+       struct dw_mci *host = slot->host;
+       unsigned long retry = 10;
+       int ret;
+       u32 ctrl;
+
+       while (1) {
+               ret = mci_send_cmd(slot,
+                    SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+               if (!ret)
+                       break;

the returned error type is timeout. Is it not necessary to read and check the HLE bit here before resending.

Quoted 44 lines
drivers/mmc/host/dw_mmc.c +13 -7
+               ctrl = mci_readl(host, CTRL);
+               ctrl |= SDMMC_CTRL_RESET;
+               mci_writel(host, CTRL, ctrl);
+
+               if (retry-- == 0) {
+                       dev_err(&slot->mmc->class_dev,"Timeout inform CIU\n");
+                       break;
+               } else
+                       dev_info(&slot->mmc->class_dev,"Retry send command\n");
+       }
 }
 
 static void dw_mci_setup_bus(struct dw_mci_slot *slot)
@@ -649,23 +675,20 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
                mci_writel(host, CLKSRC, 0);
 
                /* inform CIU */
-               mci_send_cmd(slot,
-                            SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+               dw_mci_inform_ciu(slot);
 
                /* set clock to desired speed */
                mci_writel(host, CLKDIV, div);
 
                /* inform CIU */
-               mci_send_cmd(slot,
-                            SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+               dw_mci_inform_ciu(slot);
 
                /* enable clock */
                mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE |
                           SDMMC_CLKEN_LOW_PWR) << slot->id));
 
                /* inform CIU */
-               mci_send_cmd(slot,
-                            SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+               dw_mci_inform_ciu(slot);
 
                host->current_speed = slot->clock;
        }
--

To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

author maintainer
#2 lore raw
Quoted 9 lines · Girish K S
Quoted 6 lines · Jaehoon Chung

As DesignWare spec, when inform ciu, waiting for clearing start_bit or HLE is set. In case of HLE, repeat the command.

Before the patch, repeat the below message.
mmc_host mmc0: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000) If this message is produced, repeat the send command during 10 times.

I dont understand what the above message. its not clear. can you please explain it

That message is meant that didn't send command.(debugging message at dw-mmc.c). It means also that exist the other command in buffer. So second/third command can't send. Then maybe set HLE bit. And produced that message..

Quoted 40 lines
Quoted 40 lines
---
 drivers/mmc/host/dw_mmc.c |   39 +++++++++++++++++++++++++++++++--------
 1 files changed, 31 insertions(+), 8 deletions(-)
drivers/mmc/host/dw_mmc.c +12 -2
index 72dc3cd..bec1a67 100644
@@ -603,7 +603,7 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data)
        }
 }
 
-static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
+static int mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 {
        struct dw_mci *host = slot->host;
        unsigned long timeout = jiffies + msecs_to_jiffies(500);
@@ -616,11 +616,37 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
        while (time_before(jiffies, timeout)) {
                cmd_status = mci_readl(host, CMD);
                if (!(cmd_status & SDMMC_CMD_START))
-                       return;
+                       return 0;
        }
        dev_err(&slot->mmc->class_dev,
                "Timeout sending command (cmd %#x arg %#x status %#x)\n",
                cmd, arg, cmd_status);
+
+       return -ETIMEDOUT;
+}
+
+static void dw_mci_inform_ciu(struct dw_mci_slot *slot)
+{
+       struct dw_mci *host = slot->host;
+       unsigned long retry = 10;
+       int ret;
+       u32 ctrl;
Quoted 8 lines

drivers/mmc/host/dw_mmc.c static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg) · line 639

Quoted 6 lines
drivers/mmc/host/dw_mmc.c +6 -0
+
+       while (1) {
+               ret = mci_send_cmd(slot,
+                    SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+               if (!ret)
+                       break;

the returned error type is timeout. Is it not necessary to read and check the HLE bit here before resending.

i didn't feel the necessity. if produced that message, then just repeat command. I think that its case is only HLE case.

Best Regards,
Jaehoon Chung

Quoted 45 lines
Quoted 44 lines
drivers/mmc/host/dw_mmc.c +13 -7
+               ctrl = mci_readl(host, CTRL);
+               ctrl |= SDMMC_CTRL_RESET;
+               mci_writel(host, CTRL, ctrl);
+
+               if (retry-- == 0) {
+                       dev_err(&slot->mmc->class_dev,"Timeout inform CIU\n");
+                       break;
+               } else
+                       dev_info(&slot->mmc->class_dev,"Retry send command\n");
+       }
 }
 
 static void dw_mci_setup_bus(struct dw_mci_slot *slot)
@@ -649,23 +675,20 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
                mci_writel(host, CLKSRC, 0);
 
                /* inform CIU */
-               mci_send_cmd(slot,
-                            SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+               dw_mci_inform_ciu(slot);
 
                /* set clock to desired speed */
                mci_writel(host, CLKDIV, div);
 
                /* inform CIU */
-               mci_send_cmd(slot,
-                            SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+               dw_mci_inform_ciu(slot);
 
                /* enable clock */
                mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE |
                           SDMMC_CLKEN_LOW_PWR) << slot->id));
 
                /* inform CIU */
-               mci_send_cmd(slot,
-                            SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
+               dw_mci_inform_ciu(slot);
 
                host->current_speed = slot->clock;
        }
--

To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html