LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
@ 2015-02-05 11:13 Addy Ke
  2015-02-09  4:51 ` Ulf Hansson
  2015-02-09  7:25 ` [PATCH v2 0/2] about data busy Addy Ke
  0 siblings, 2 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-05 11:13 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders, sonnyrao, amstan
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip, zhenfu.fang, cf, lintao, chenfen, zyf, xjq,
	huangtao, zyw, yzq, hj, kever.yang, zhangqing, hl, Addy Ke

Because of some uncertain factors, such as worse card or worse hardware,
DAT[3:0](the data lines) may be pulled down by card, and mmc controller
will be in busy state. This should not happend when mmc controller
send command to update card clocks. If this happends, mci_send_cmd will
be failed and we will get 'Timeout sending command', and then system will
be blocked. To avoid this, we need reset mmc controller.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
 drivers/mmc/host/dw_mmc.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 4d2e3c2..b1d6dfb 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -100,6 +100,7 @@ struct idmac_desc {
 };
 #endif /* CONFIG_MMC_DW_IDMAC */
 
+static int dw_mci_card_busy(struct mmc_host *mmc);
 static bool dw_mci_reset(struct dw_mci *host);
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
 
@@ -888,6 +889,26 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 		cmd, arg, cmd_status);
 }
 
+static void dw_mci_wait_busy(struct dw_mci_slot *slot)
+{
+	struct dw_mci *host = slot->host;
+	unsigned long timeout = jiffies + msecs_to_jiffies(500);
+
+	while (time_before(jiffies, timeout)) {
+		if (!dw_mci_card_busy(slot->mmc))
+			return;
+	}
+	dev_err(host->dev, "Data busy (status %#x)\n",
+		mci_readl(slot->host, STATUS));
+
+	/*
+	 * Data busy, this should not happend when mmc controller send command
+	 * to update card clocks in non-volt-switch state. If it happends, we
+	 * should reset controller to avoid getting "Timeout sending command".
+	 */
+	dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
+}
+
 static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 {
 	struct dw_mci *host = slot->host;
@@ -899,6 +920,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 	/* We must continue to set bit 28 in CMD until the change is complete */
 	if (host->state == STATE_WAITING_CMD11_DONE)
 		sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
+	else
+		dw_mci_wait_busy(slot);
 
 	if (!clock) {
 		mci_writel(host, CLKENA, 0);
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-05 11:13 [PATCH] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
@ 2015-02-09  4:51 ` Ulf Hansson
  2015-02-09  6:56   ` Addy
  2015-02-09  7:25 ` [PATCH v2 0/2] about data busy Addy Ke
  1 sibling, 1 reply; 43+ messages in thread
From: Ulf Hansson @ 2015-02-09  4:51 UTC (permalink / raw)
  To: Addy Ke
  Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Randy Dunlap, tgih.jun, Jaehoon Chung, Chris Ball,
	Dinh Nguyen, Heiko Stübner, Olof Johansson, Doug Anderson,
	Sonny Rao, Alexandru Stan, devicetree, linux-doc, linux-kernel,
	linux-mmc, linux-arm-kernel, open list:ARM/Rockchip SoC...,
	zhenfu.fang, Eddie Cai, lintao, chenfen, zyf, Jianqun Xu,
	Tao Huang, Chris Zhong, 姚智情,
	Han Jiang, Kever Yang, zhangqing, Lin Huang

On 5 February 2015 at 12:13, Addy Ke <addy.ke@rock-chips.com> wrote:
>
> Because of some uncertain factors, such as worse card or worse hardware,
> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
> will be in busy state. This should not happend when mmc controller
> send command to update card clocks. If this happends, mci_send_cmd will
> be failed and we will get 'Timeout sending command', and then system will
> be blocked. To avoid this, we need reset mmc controller.
>
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>


Hi Addy,

Should I consider $subject patch as a better option to the one below?

[PATCH] mmc: dw_mmc: rockchip: Add DW_MCI_QUIRK_RETRY_DELAY
https://lkml.org/lkml/2015/1/13/562

Kind regards
Uffe


> ---
>  drivers/mmc/host/dw_mmc.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 4d2e3c2..b1d6dfb 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -100,6 +100,7 @@ struct idmac_desc {
>  };
>  #endif /* CONFIG_MMC_DW_IDMAC */
>
> +static int dw_mci_card_busy(struct mmc_host *mmc);
>  static bool dw_mci_reset(struct dw_mci *host);
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>
> @@ -888,6 +889,26 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>                 cmd, arg, cmd_status);
>  }
>
> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
> +{
> +       struct dw_mci *host = slot->host;
> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
> +
> +       while (time_before(jiffies, timeout)) {
> +               if (!dw_mci_card_busy(slot->mmc))
> +                       return;
> +       }
> +       dev_err(host->dev, "Data busy (status %#x)\n",
> +               mci_readl(slot->host, STATUS));
> +
> +       /*
> +        * Data busy, this should not happend when mmc controller send command
> +        * to update card clocks in non-volt-switch state. If it happends, we
> +        * should reset controller to avoid getting "Timeout sending command".
> +        */
> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
> +}
> +
>  static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>  {
>         struct dw_mci *host = slot->host;
> @@ -899,6 +920,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>         /* We must continue to set bit 28 in CMD until the change is complete */
>         if (host->state == STATE_WAITING_CMD11_DONE)
>                 sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
> +       else
> +               dw_mci_wait_busy(slot);
>
>         if (!clock) {
>                 mci_writel(host, CLKENA, 0);
> --
> 1.8.3.2
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-09  4:51 ` Ulf Hansson
@ 2015-02-09  6:56   ` Addy
  2015-02-09  7:04     ` Jaehoon Chung
  0 siblings, 1 reply; 43+ messages in thread
From: Addy @ 2015-02-09  6:56 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Randy Dunlap, tgih.jun, Jaehoon Chung, Chris Ball,
	Dinh Nguyen, Heiko Stübner, Olof Johansson, Doug Anderson,
	Sonny Rao, Alexandru Stan, devicetree, linux-doc, linux-kernel,
	linux-mmc, linux-arm-kernel, open list:ARM/Rockchip SoC...,
	zhenfu.fang, Eddie Cai, lintao, chenfen, zyf, Jianqun Xu,
	Tao Huang, Chris Zhong, 姚智情,
	Han Jiang, Kever Yang, zhangqing, Lin Huang



On 2015.02.09 12:51, Ulf Hansson wrote:
> On 5 February 2015 at 12:13, Addy Ke <addy.ke@rock-chips.com> wrote:
>> Because of some uncertain factors, such as worse card or worse hardware,
>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>> will be in busy state. This should not happend when mmc controller
>> send command to update card clocks. If this happends, mci_send_cmd will
>> be failed and we will get 'Timeout sending command', and then system will
>> be blocked. To avoid this, we need reset mmc controller.
>>
>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>
> Hi Addy,
>
> Should I consider $subject patch as a better option to the one below?
No:
This patch fix the bug, which can be found by script:
     cd /sys/bus/platform/drivers/dwmmc_rockchip
     for i in $(seq 1 10000); do
       echo "========================" $i
       echo ff0c0000.dwmmc > unbind
       sleep .5
       echo ff0c0000.dwmmc > bind
       sleep 2
     done

> [PATCH] mmc: dw_mmc: rockchip: Add DW_MCI_QUIRK_RETRY_DELAY
This patch is for tuning issue: we should delay until card go to idle 
state, when the previous command return error.
> https://lkml.org/lkml/2015/1/13/562
>
> Kind regards
> Uffe
>
>
>> ---
>>   drivers/mmc/host/dw_mmc.c | 23 +++++++++++++++++++++++
>>   1 file changed, 23 insertions(+)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 4d2e3c2..b1d6dfb 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>   };
>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>
>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>   static bool dw_mci_reset(struct dw_mci *host);
>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>
>> @@ -888,6 +889,26 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>                  cmd, arg, cmd_status);
>>   }
>>
>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>> +{
>> +       struct dw_mci *host = slot->host;
>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>> +
>> +       while (time_before(jiffies, timeout)) {
>> +               if (!dw_mci_card_busy(slot->mmc))
>> +                       return;
>> +       }
>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>> +               mci_readl(slot->host, STATUS));
>> +
>> +       /*
>> +        * Data busy, this should not happend when mmc controller send command
>> +        * to update card clocks in non-volt-switch state. If it happends, we
>> +        * should reset controller to avoid getting "Timeout sending command".
>> +        */
>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>> +}
>> +
>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>   {
>>          struct dw_mci *host = slot->host;
>> @@ -899,6 +920,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>> +       else
>> +               dw_mci_wait_busy(slot);
>>
>>          if (!clock) {
>>                  mci_writel(host, CLKENA, 0);
>> --
>> 1.8.3.2
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-09  6:56   ` Addy
@ 2015-02-09  7:04     ` Jaehoon Chung
  2015-02-09  9:17       ` addy ke
  0 siblings, 1 reply; 43+ messages in thread
From: Jaehoon Chung @ 2015-02-09  7:04 UTC (permalink / raw)
  To: Addy, Ulf Hansson
  Cc: Rob Herring, Paweł Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Randy Dunlap, tgih.jun, Chris Ball, Dinh Nguyen,
	Heiko Stübner, Olof Johansson, Doug Anderson, Sonny Rao,
	Alexandru Stan, devicetree, linux-doc, linux-kernel, linux-mmc,
	linux-arm-kernel, open list:ARM/Rockchip SoC...,
	zhenfu.fang, Eddie Cai, lintao, chenfen, zyf, Jianqun Xu,
	Tao Huang, Chris Zhong, 姚智情,
	Han Jiang, Kever Yang, zhangqing, Lin Huang

On 02/09/2015 03:56 PM, Addy wrote:
> 
> 
> On 2015.02.09 12:51, Ulf Hansson wrote:
>> On 5 February 2015 at 12:13, Addy Ke <addy.ke@rock-chips.com> wrote:
>>> Because of some uncertain factors, such as worse card or worse hardware,
>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>> will be in busy state. This should not happend when mmc controller
>>> send command to update card clocks. If this happends, mci_send_cmd will
>>> be failed and we will get 'Timeout sending command', and then system will
>>> be blocked. To avoid this, we need reset mmc controller.

I know that it needs to check whether card is busy or not, before clock-off.
This patch seems to related with it. right?

Best Regards,
Jaehoon Chung

>>>
>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>
>> Hi Addy,
>>
>> Should I consider $subject patch as a better option to the one below?
> No:
> This patch fix the bug, which can be found by script:
>     cd /sys/bus/platform/drivers/dwmmc_rockchip
>     for i in $(seq 1 10000); do
>       echo "========================" $i
>       echo ff0c0000.dwmmc > unbind
>       sleep .5
>       echo ff0c0000.dwmmc > bind
>       sleep 2
>     done
> 
>> [PATCH] mmc: dw_mmc: rockchip: Add DW_MCI_QUIRK_RETRY_DELAY
> This patch is for tuning issue: we should delay until card go to idle state, when the previous command return error.
>> https://lkml.org/lkml/2015/1/13/562
>>
>> Kind regards
>> Uffe
>>
>>
>>> ---
>>>   drivers/mmc/host/dw_mmc.c | 23 +++++++++++++++++++++++
>>>   1 file changed, 23 insertions(+)
>>>
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index 4d2e3c2..b1d6dfb 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>   };
>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>
>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>
>>> @@ -888,6 +889,26 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>                  cmd, arg, cmd_status);
>>>   }
>>>
>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>> +{
>>> +       struct dw_mci *host = slot->host;
>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>> +
>>> +       while (time_before(jiffies, timeout)) {
>>> +               if (!dw_mci_card_busy(slot->mmc))
>>> +                       return;
>>> +       }
>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>> +               mci_readl(slot->host, STATUS));
>>> +
>>> +       /*
>>> +        * Data busy, this should not happend when mmc controller send command
>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>> +        * should reset controller to avoid getting "Timeout sending command".
>>> +        */
>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>> +}
>>> +
>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>   {
>>>          struct dw_mci *host = slot->host;
>>> @@ -899,6 +920,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>> +       else
>>> +               dw_mci_wait_busy(slot);
>>>
>>>          if (!clock) {
>>>                  mci_writel(host, CLKENA, 0);
>>> -- 
>>> 1.8.3.2
>>>
>>>
>>> -- 
>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>>
> 
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 0/2] about data busy
  2015-02-05 11:13 [PATCH] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
  2015-02-09  4:51 ` Ulf Hansson
@ 2015-02-09  7:25 ` Addy Ke
  2015-02-09  7:25   ` [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
                     ` (2 more replies)
  1 sibling, 3 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-09  7:25 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders, sonnyrao, amstan, djkurtz
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip, zhenfu.fang, cf, lintao, chenfen, zyf, xjq,
	huangtao, zyw, yzq, hj, kever.yang, zhangqing, hl, Addy Ke

Addy Ke (2):
  mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  mmc: dw_mmc: Don't start command while data busy

 drivers/mmc/host/dw_mmc.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

-- 
Changes in v2:
- add new patch to handle data busy when start command
- add cpu_relaxed, suggested by Daniel Kurtz <djkurtz@chromium.org>
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-09  7:25 ` [PATCH v2 0/2] about data busy Addy Ke
@ 2015-02-09  7:25   ` Addy Ke
  2015-02-09 10:01     ` Jaehoon Chung
  2015-02-10 15:22     ` Alim Akhtar
  2015-02-09  7:25   ` [PATCH v2 2/2] mmc: dw_mmc: Don't start command while data busy Addy Ke
  2015-02-13 11:52   ` [PATCH v3 0/3] about " Addy Ke
  2 siblings, 2 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-09  7:25 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders, sonnyrao, amstan, djkurtz
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip, zhenfu.fang, cf, lintao, chenfen, zyf, xjq,
	huangtao, zyw, yzq, hj, kever.yang, zhangqing, hl, Addy Ke

Because of some uncertain factors, such as worse card or worse hardware,
DAT[3:0](the data lines) may be pulled down by card, and mmc controller
will be in busy state. This should not happend when mmc controller
send command to update card clocks. If this happends, mci_send_cmd will
be failed and we will get 'Timeout sending command', and then system will
be blocked. To avoid this, we need reset mmc controller.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
 drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 4d2e3c2..b0b57e3 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -100,6 +100,7 @@ struct idmac_desc {
 };
 #endif /* CONFIG_MMC_DW_IDMAC */
 
+static int dw_mci_card_busy(struct mmc_host *mmc);
 static bool dw_mci_reset(struct dw_mci *host);
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
 
@@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 		cmd, arg, cmd_status);
 }
 
+static void dw_mci_wait_busy(struct dw_mci_slot *slot)
+{
+	struct dw_mci *host = slot->host;
+	unsigned long timeout = jiffies + msecs_to_jiffies(500);
+
+	do {
+		if (!dw_mci_card_busy(slot->mmc))
+			return;
+		cpu_relax();
+	} while (time_before(jiffies, timeout));
+
+	dev_err(host->dev, "Data busy (status %#x)\n",
+		mci_readl(slot->host, STATUS));
+
+	/*
+	 * Data busy, this should not happend when mmc controller send command
+	 * to update card clocks in non-volt-switch state. If it happends, we
+	 * should reset controller to avoid getting "Timeout sending command".
+	 */
+	dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
+
+	/* Fail to reset controller or still data busy, WARN_ON! */
+	WARN_ON(dw_mci_card_busy(slot->mmc));
+}
+
 static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 {
 	struct dw_mci *host = slot->host;
@@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 	/* We must continue to set bit 28 in CMD until the change is complete */
 	if (host->state == STATE_WAITING_CMD11_DONE)
 		sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
+	else
+		dw_mci_wait_busy(slot);
 
 	if (!clock) {
 		mci_writel(host, CLKENA, 0);
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 2/2] mmc: dw_mmc: Don't start command while data busy
  2015-02-09  7:25 ` [PATCH v2 0/2] about data busy Addy Ke
  2015-02-09  7:25   ` [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
@ 2015-02-09  7:25   ` Addy Ke
  2015-02-13 11:52   ` [PATCH v3 0/3] about " Addy Ke
  2 siblings, 0 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-09  7:25 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders, sonnyrao, amstan, djkurtz
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip, zhenfu.fang, cf, lintao, chenfen, zyf, xjq,
	huangtao, zyw, yzq, hj, kever.yang, zhangqing, hl, Addy Ke

We should wait for data busy here in non-volt-switch state.
This may happend when sdio sends CMD53.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
 drivers/mmc/host/dw_mmc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index b0b57e3..b40080d 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1007,6 +1007,13 @@ static void __dw_mci_start_request(struct dw_mci *host,
 		mci_writel(host, BLKSIZ, data->blksz);
 	}
 
+	/*
+	 * We should wait for data busy here in non-volt-switch state.
+	 * This may happend when sdio sends CMD53.
+	 */
+	if (host->state != STATE_WAITING_CMD11_DONE)
+		dw_mci_wait_busy(slot);
+
 	cmdflags = dw_mci_prepare_command(slot->mmc, cmd);
 
 	/* this is the first command, send the initialization clock */
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-09  7:04     ` Jaehoon Chung
@ 2015-02-09  9:17       ` addy ke
  0 siblings, 0 replies; 43+ messages in thread
From: addy ke @ 2015-02-09  9:17 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson
  Cc: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, chris, dinguyen, heiko, olof, dianders,
	sonnyrao, amstan, devicetree, linux-doc, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, zhenfu.fang, cf, lintao,
	chenfen, zyf, xjq, huangtao, zyw, yzq, hj, kever.yang, zhangqing,
	hl



On 2015/2/9 15:04, Jaehoon Chung wrote:
> On 02/09/2015 03:56 PM, Addy wrote:
>>
>>
>> On 2015.02.09 12:51, Ulf Hansson wrote:
>>> On 5 February 2015 at 12:13, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>> Because of some uncertain factors, such as worse card or worse hardware,
>>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>>> will be in busy state. This should not happend when mmc controller
>>>> send command to update card clocks. If this happends, mci_send_cmd will
>>>> be failed and we will get 'Timeout sending command', and then system will
>>>> be blocked. To avoid this, we need reset mmc controller.
> 
> I know that it needs to check whether card is busy or not, before clock-off.
> This patch seems to related with it. right?

Yes, it is.

> 
> Best Regards,
> Jaehoon Chung
> 
>>>>
>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>
>>> Hi Addy,
>>>
>>> Should I consider $subject patch as a better option to the one below?
>> No:
>> This patch fix the bug, which can be found by script:
>>     cd /sys/bus/platform/drivers/dwmmc_rockchip
>>     for i in $(seq 1 10000); do
>>       echo "========================" $i
>>       echo ff0c0000.dwmmc > unbind
>>       sleep .5
>>       echo ff0c0000.dwmmc > bind
>>       sleep 2
>>     done
>>
>>> [PATCH] mmc: dw_mmc: rockchip: Add DW_MCI_QUIRK_RETRY_DELAY
>> This patch is for tuning issue: we should delay until card go to idle state, when the previous command return error.
>>> https://lkml.org/lkml/2015/1/13/562
>>>
>>> Kind regards
>>> Uffe
>>>
>>>
>>>> ---
>>>>   drivers/mmc/host/dw_mmc.c | 23 +++++++++++++++++++++++
>>>>   1 file changed, 23 insertions(+)
>>>>
>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>> index 4d2e3c2..b1d6dfb 100644
>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>>   };
>>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>>
>>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>
>>>> @@ -888,6 +889,26 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>>                  cmd, arg, cmd_status);
>>>>   }
>>>>
>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>>> +{
>>>> +       struct dw_mci *host = slot->host;
>>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>>> +
>>>> +       while (time_before(jiffies, timeout)) {
>>>> +               if (!dw_mci_card_busy(slot->mmc))
>>>> +                       return;
>>>> +       }
>>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>>> +               mci_readl(slot->host, STATUS));
>>>> +
>>>> +       /*
>>>> +        * Data busy, this should not happend when mmc controller send command
>>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>>> +        * should reset controller to avoid getting "Timeout sending command".
>>>> +        */
>>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>>> +}
>>>> +
>>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>   {
>>>>          struct dw_mci *host = slot->host;
>>>> @@ -899,6 +920,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>> +       else
>>>> +               dw_mci_wait_busy(slot);
>>>>
>>>>          if (!clock) {
>>>>                  mci_writel(host, CLKENA, 0);
>>>> -- 
>>>> 1.8.3.2
>>>>
>>>>
>>>> -- 
>>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>>
>>
>>
>>
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-09  7:25   ` [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
@ 2015-02-09 10:01     ` Jaehoon Chung
  2015-02-11  3:07       ` Addy
  2015-02-10 15:22     ` Alim Akhtar
  1 sibling, 1 reply; 43+ messages in thread
From: Jaehoon Chung @ 2015-02-09 10:01 UTC (permalink / raw)
  To: Addy Ke, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rdunlap, tgih.jun, chris, ulf.hansson, dinguyen, heiko,
	olof, dianders, sonnyrao, amstan, djkurtz
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip, zhenfu.fang, cf, lintao, chenfen, zyf, xjq,
	huangtao, zyw, yzq, hj, kever.yang, zhangqing, hl

Hi, Addy.

On 02/09/2015 04:25 PM, Addy Ke wrote:
> Because of some uncertain factors, such as worse card or worse hardware,
> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
> will be in busy state. This should not happend when mmc controller
> send command to update card clocks. If this happends, mci_send_cmd will
> be failed and we will get 'Timeout sending command', and then system will
> be blocked. To avoid this, we need reset mmc controller.
> 
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
>  drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 4d2e3c2..b0b57e3 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -100,6 +100,7 @@ struct idmac_desc {
>  };
>  #endif /* CONFIG_MMC_DW_IDMAC */
>  
> +static int dw_mci_card_busy(struct mmc_host *mmc);
>  static bool dw_mci_reset(struct dw_mci *host);
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>  
> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>  		cmd, arg, cmd_status);
>  }
>  
> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
> +{
> +	struct dw_mci *host = slot->host;
> +	unsigned long timeout = jiffies + msecs_to_jiffies(500);
> +
> +	do {
> +		if (!dw_mci_card_busy(slot->mmc))
> +			return;
> +		cpu_relax();
> +	} while (time_before(jiffies, timeout));
> +
> +	dev_err(host->dev, "Data busy (status %#x)\n",
> +		mci_readl(slot->host, STATUS));
> +
> +	/*
> +	 * Data busy, this should not happend when mmc controller send command
> +	 * to update card clocks in non-volt-switch state. If it happends, we
> +	 * should reset controller to avoid getting "Timeout sending command".
> +	 */
> +	dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);

If reset is failed, then dw_mci_ctrl_reset should return "false".

	ret = dw_mci_ctrl_reset();

	WARN_ON(!ret || dw_mci_card_busy(slot->mmc));

Is it right?

In my experiment, if reset is failed or card is busy, eMMC can't work anymore..right?
I think this patch is reasonable to prevent blocking issue.

Best Regards,
Jaehoon Chung


> +
> +	/* Fail to reset controller or still data busy, WARN_ON! */
> +	WARN_ON(dw_mci_card_busy(slot->mmc));
> +}
> +
>  static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>  {
>  	struct dw_mci *host = slot->host;
> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>  	/* We must continue to set bit 28 in CMD until the change is complete */
>  	if (host->state == STATE_WAITING_CMD11_DONE)
>  		sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
> +	else
> +		dw_mci_wait_busy(slot);
>  
>  	if (!clock) {
>  		mci_writel(host, CLKENA, 0);
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-09  7:25   ` [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
  2015-02-09 10:01     ` Jaehoon Chung
@ 2015-02-10 15:22     ` Alim Akhtar
  2015-02-11  2:57       ` Addy
  1 sibling, 1 reply; 43+ messages in thread
From: Alim Akhtar @ 2015-02-10 15:22 UTC (permalink / raw)
  To: Addy Ke
  Cc: robh+dt, pawel.moll, Mark Rutland, ijc+devicetree, galak,
	rdunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball, Ulf Hansson,
	dinguyen, Heiko Stübner, Olof Johansson, Douglas Anderson,
	Sonny Rao, amstan, djkurtz, huangtao, devicetree, hl, linux-doc,
	yzq, zyw, zhangqing, linux-mmc, linux-kernel, kever.yang, lintao,
	linux-rockchip, xjq, zhenfu.fang, chenfen, cf, hj,
	linux-arm-kernel, zyf

Hi Addy,

On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
> Because of some uncertain factors, such as worse card or worse hardware,
> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
> will be in busy state. This should not happend when mmc controller
> send command to update card clocks. If this happends, mci_send_cmd will
> be failed and we will get 'Timeout sending command', and then system will
> be blocked. To avoid this, we need reset mmc controller.
>
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
>  drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 4d2e3c2..b0b57e3 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -100,6 +100,7 @@ struct idmac_desc {
>  };
>  #endif /* CONFIG_MMC_DW_IDMAC */
>
> +static int dw_mci_card_busy(struct mmc_host *mmc);
>  static bool dw_mci_reset(struct dw_mci *host);
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>
> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>                 cmd, arg, cmd_status);
>  }
>
> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
> +{
> +       struct dw_mci *host = slot->host;
> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
> +
Why 500 msec?

> +       do {
> +               if (!dw_mci_card_busy(slot->mmc))
> +                       return;
> +               cpu_relax();
> +       } while (time_before(jiffies, timeout));
> +
> +       dev_err(host->dev, "Data busy (status %#x)\n",
> +               mci_readl(slot->host, STATUS));
> +
> +       /*
> +        * Data busy, this should not happend when mmc controller send command
> +        * to update card clocks in non-volt-switch state. If it happends, we
> +        * should reset controller to avoid getting "Timeout sending command".
> +        */
> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
> +
Why you need to reset all blocks? may be CTRL_RESET is good enough here.

> +       /* Fail to reset controller or still data busy, WARN_ON! */
> +       WARN_ON(dw_mci_card_busy(slot->mmc));
> +}
> +
>  static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>  {
>         struct dw_mci *host = slot->host;
> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>         /* We must continue to set bit 28 in CMD until the change is complete */
>         if (host->state == STATE_WAITING_CMD11_DONE)
>                 sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
> +       else
> +               dw_mci_wait_busy(slot);
>
hmm...I would suggest you to call dw_mci_wait_busy() from inside
mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
in multiple cases.see [1]

[1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140

>         if (!clock) {
>                 mci_writel(host, CLKENA, 0);
> --
> 1.8.3.2
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



-- 
Regards,
Alim

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-10 15:22     ` Alim Akhtar
@ 2015-02-11  2:57       ` Addy
  2015-02-11 11:58         ` Andrzej Hajda
  0 siblings, 1 reply; 43+ messages in thread
From: Addy @ 2015-02-11  2:57 UTC (permalink / raw)
  To: Alim Akhtar
  Cc: robh+dt, pawel.moll, Mark Rutland, ijc+devicetree, galak,
	rdunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball, Ulf Hansson,
	dinguyen, Heiko Stübner, Olof Johansson, Douglas Anderson,
	Sonny Rao, amstan, djkurtz, huangtao, devicetree, hl, linux-doc,
	yzq, zyw, zhangqing, linux-mmc, linux-kernel, kever.yang, lintao,
	linux-rockchip, xjq, zhenfu.fang, chenfen, cf, hj,
	linux-arm-kernel, zyf


On 2015/02/10 23:22, Alim Akhtar wrote:
> Hi Addy,
>
> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> Because of some uncertain factors, such as worse card or worse hardware,
>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>> will be in busy state. This should not happend when mmc controller
>> send command to update card clocks. If this happends, mci_send_cmd will
>> be failed and we will get 'Timeout sending command', and then system will
>> be blocked. To avoid this, we need reset mmc controller.
>>
>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>> ---
>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>   1 file changed, 28 insertions(+)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 4d2e3c2..b0b57e3 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>   };
>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>
>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>   static bool dw_mci_reset(struct dw_mci *host);
>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>
>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>                  cmd, arg, cmd_status);
>>   }
>>
>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>> +{
>> +       struct dw_mci *host = slot->host;
>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>> +
> Why 500 msec?
This timeout value is the same as  mci_send_cmd:
static void 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);
         ....
}

I have not clear that which is suitable.
Do you have any suggestion on it?
>
>> +       do {
>> +               if (!dw_mci_card_busy(slot->mmc))
>> +                       return;
>> +               cpu_relax();
>> +       } while (time_before(jiffies, timeout));
>> +
>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>> +               mci_readl(slot->host, STATUS));
>> +
>> +       /*
>> +        * Data busy, this should not happend when mmc controller send command
>> +        * to update card clocks in non-volt-switch state. If it happends, we
>> +        * should reset controller to avoid getting "Timeout sending command".
>> +        */
>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>> +
> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
I have tested on rk3288, if only reset ctroller, data busy bit will not 
be cleaned,and we will still get

"Timeout sending command".

>
>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>> +}
>> +
>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>   {
>>          struct dw_mci *host = slot->host;
>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>> +       else
>> +               dw_mci_wait_busy(slot);
>>
> hmm...I would suggest you to call dw_mci_wait_busy() from inside
> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
> in multiple cases.see [1]
>
> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
I think this patch is more reasonable.
So I will resend patches based on this patch.
thank you!
>
>>          if (!clock) {
>>                  mci_writel(host, CLKENA, 0);
>> --
>> 1.8.3.2
>>
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-09 10:01     ` Jaehoon Chung
@ 2015-02-11  3:07       ` Addy
  0 siblings, 0 replies; 43+ messages in thread
From: Addy @ 2015-02-11  3:07 UTC (permalink / raw)
  To: Jaehoon Chung, robh+dt, pawel.moll, mark.rutland, ijc+devicetree,
	galak, rdunlap, tgih.jun, chris, ulf.hansson, dinguyen, heiko,
	olof, dianders, sonnyrao, amstan, djkurtz
  Cc: devicetree, linux-doc, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip, zhenfu.fang, cf, lintao, chenfen, zyf, xjq,
	huangtao, zyw, yzq, hj, kever.yang, zhangqing, hl


On 2015/02/09 18:01, Jaehoon Chung wrote:
> Hi, Addy.
>
> On 02/09/2015 04:25 PM, Addy Ke wrote:
>> Because of some uncertain factors, such as worse card or worse hardware,
>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>> will be in busy state. This should not happend when mmc controller
>> send command to update card clocks. If this happends, mci_send_cmd will
>> be failed and we will get 'Timeout sending command', and then system will
>> be blocked. To avoid this, we need reset mmc controller.
>>
>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>> ---
>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>   1 file changed, 28 insertions(+)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 4d2e3c2..b0b57e3 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>   };
>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>   
>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>   static bool dw_mci_reset(struct dw_mci *host);
>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>   
>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>   		cmd, arg, cmd_status);
>>   }
>>   
>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>> +{
>> +	struct dw_mci *host = slot->host;
>> +	unsigned long timeout = jiffies + msecs_to_jiffies(500);
>> +
>> +	do {
>> +		if (!dw_mci_card_busy(slot->mmc))
>> +			return;
>> +		cpu_relax();
>> +	} while (time_before(jiffies, timeout));
>> +
>> +	dev_err(host->dev, "Data busy (status %#x)\n",
>> +		mci_readl(slot->host, STATUS));
>> +
>> +	/*
>> +	 * Data busy, this should not happend when mmc controller send command
>> +	 * to update card clocks in non-volt-switch state. If it happends, we
>> +	 * should reset controller to avoid getting "Timeout sending command".
>> +	 */
>> +	dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
> If reset is failed, then dw_mci_ctrl_reset should return "false".
>
> 	ret = dw_mci_ctrl_reset();
>
> 	WARN_ON(!ret || dw_mci_card_busy(slot->mmc));
>
> Is it right?
you are right, and I will update it in my next version patch. thank you.
>
> In my experiment, if reset is failed or card is busy, eMMC can't work anymore..right?
> I think this patch is reasonable to prevent blocking issue.
>
> Best Regards,
> Jaehoon Chung
>
>
>> +
>> +	/* Fail to reset controller or still data busy, WARN_ON! */
>> +	WARN_ON(dw_mci_card_busy(slot->mmc));
>> +}
>> +
>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>   {
>>   	struct dw_mci *host = slot->host;
>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>   	/* We must continue to set bit 28 in CMD until the change is complete */
>>   	if (host->state == STATE_WAITING_CMD11_DONE)
>>   		sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>> +	else
>> +		dw_mci_wait_busy(slot);
>>   
>>   	if (!clock) {
>>   		mci_writel(host, CLKENA, 0);
>>
>
>
>



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-11  2:57       ` Addy
@ 2015-02-11 11:58         ` Andrzej Hajda
  2015-02-11 23:20           ` Alim Akhtar
  0 siblings, 1 reply; 43+ messages in thread
From: Andrzej Hajda @ 2015-02-11 11:58 UTC (permalink / raw)
  To: Addy, Alim Akhtar
  Cc: robh+dt, pawel.moll, Mark Rutland, ijc+devicetree, galak,
	rdunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball, Ulf Hansson,
	dinguyen, Heiko Stübner, Olof Johansson, Douglas Anderson,
	Sonny Rao, amstan, djkurtz, huangtao, devicetree, hl, linux-doc,
	yzq, zyw, zhangqing, linux-mmc, linux-kernel, kever.yang

Hi Alim,

On 02/11/2015 03:57 AM, Addy wrote:
> 
> On 2015/02/10 23:22, Alim Akhtar wrote:
>> Hi Addy,
>>
>> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>> Because of some uncertain factors, such as worse card or worse hardware,
>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>> will be in busy state. This should not happend when mmc controller
>>> send command to update card clocks. If this happends, mci_send_cmd will
>>> be failed and we will get 'Timeout sending command', and then system will
>>> be blocked. To avoid this, we need reset mmc controller.
>>>
>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>> ---
>>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>>   1 file changed, 28 insertions(+)
>>>
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index 4d2e3c2..b0b57e3 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>   };
>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>
>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>
>>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>                  cmd, arg, cmd_status);
>>>   }
>>>
>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>> +{
>>> +       struct dw_mci *host = slot->host;
>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>> +
>> Why 500 msec?
> This timeout value is the same as  mci_send_cmd:
> static void 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);
>          ....
> }
> 
> I have not clear that which is suitable.
> Do you have any suggestion on it?
>>
>>> +       do {
>>> +               if (!dw_mci_card_busy(slot->mmc))
>>> +                       return;
>>> +               cpu_relax();
>>> +       } while (time_before(jiffies, timeout));
>>> +
>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>> +               mci_readl(slot->host, STATUS));
>>> +
>>> +       /*
>>> +        * Data busy, this should not happend when mmc controller send command
>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>> +        * should reset controller to avoid getting "Timeout sending command".
>>> +        */
>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>> +
>> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
> I have tested on rk3288, if only reset ctroller, data busy bit will not 
> be cleaned,and we will still get
> 
> "Timeout sending command".
> 
>>
>>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>>> +}
>>> +
>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>   {
>>>          struct dw_mci *host = slot->host;
>>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>> +       else
>>> +               dw_mci_wait_busy(slot);
>>>
>> hmm...I would suggest you to call dw_mci_wait_busy() from inside
>> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
>> in multiple cases.see [1]
>>
>> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
> I think this patch is more reasonable.
> So I will resend patches based on this patch.
> thank you!

I have tested your patches instead [1] above and they do not solve my issue:
Board: odroid-xu3/exynos5422/dw_mmc_250a.
MMC card: absent, broken-cd quirk
SD card: present

System hangs during boot after few minutes kernel spits:
[  242.188098] INFO: task kworker/u16:1:50 blocked for more than 120
seconds.
[  242.193524]       Not tainted
3.19.0-next-20150210-00002-gf96831b-dirty #3834
[  242.200622] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[  242.208422] kworker/u16:1   D c04766ac     0    50      2 0x00000000
[  242.214756] Workqueue: kmmcd mmc_rescan
[  242.218553] [<c04766ac>] (__schedule) from [<c0476a58>]
(schedule+0x34/0x98)
[  242.225591] [<c0476a58>] (schedule) from [<c047a4dc>]
(schedule_timeout+0x110/0x164)
[  242.233302] [<c047a4dc>] (schedule_timeout) from [<c04774f0>]
(wait_for_common+0xb8/0x14c)
[  242.241539] [<c04774f0>] (wait_for_common) from [<c0362138>]
(mmc_wait_for_req+0x68/0x17c)
[  242.249861] [<c0362138>] (mmc_wait_for_req) from [<c03622cc>]
(mmc_wait_for_cmd+0x80/0xa0)
[  242.258002] [<c03622cc>] (mmc_wait_for_cmd) from [<c0367e50>]
(mmc_go_idle+0x78/0xf8)
[  242.265796] [<c0367e50>] (mmc_go_idle) from [<c0363e2c>]
(mmc_rescan+0x280/0x314)
[  242.273253] [<c0363e2c>] (mmc_rescan) from [<c0034764>]
(process_one_work+0x120/0x324)
[  242.281135] [<c0034764>] (process_one_work) from [<c00349cc>]
(worker_thread+0x30/0x42c)
[  242.289194] [<c00349cc>] (worker_thread) from [<c003926c>]
(kthread+0xd8/0xf4)
[  242.296389] [<c003926c>] (kthread) from [<c000e7c0>]
(ret_from_fork+0x14/0x34)

Just for record, Exynos4412/dw_mmc_240a with the same configuration
(no MMC card, broken-cd) works OK without patches.


Regards
Andrzej

>>
>>>          if (!clock) {
>>>                  mci_writel(host, CLKENA, 0);
>>> --
>>> 1.8.3.2
>>>
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>>
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-11 11:58         ` Andrzej Hajda
@ 2015-02-11 23:20           ` Alim Akhtar
  2015-02-12  2:28             ` addy ke
  2015-02-12 11:13             ` Andrzej Hajda
  0 siblings, 2 replies; 43+ messages in thread
From: Alim Akhtar @ 2015-02-11 23:20 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Addy, robh+dt, pawel.moll, Mark Rutland, ijc+devicetree,
	Kumar Gala, rdunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Ulf Hansson, dinguyen, Heiko Stübner, Olof Johansson,
	Douglas Anderson, Sonny Rao, Alexandru Stan, Daniel Kurtz,
	Tao Huang, devicetree, Lin Huang, linux-doc,
	姚智情,
	Chris Zhong, zhangqing, linux-mmc, linux-kernel, Kever Yang

Hi Andrzej,

On Wed, Feb 11, 2015 at 5:28 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
> Hi Alim,
>
> On 02/11/2015 03:57 AM, Addy wrote:
>>
>> On 2015/02/10 23:22, Alim Akhtar wrote:
>>> Hi Addy,
>>>
>>> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>> Because of some uncertain factors, such as worse card or worse hardware,
>>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>>> will be in busy state. This should not happend when mmc controller
>>>> send command to update card clocks. If this happends, mci_send_cmd will
>>>> be failed and we will get 'Timeout sending command', and then system will
>>>> be blocked. To avoid this, we need reset mmc controller.
>>>>
>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>> ---
>>>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>>>   1 file changed, 28 insertions(+)
>>>>
>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>> index 4d2e3c2..b0b57e3 100644
>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>>   };
>>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>>
>>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>
>>>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>>                  cmd, arg, cmd_status);
>>>>   }
>>>>
>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>>> +{
>>>> +       struct dw_mci *host = slot->host;
>>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>>> +
>>> Why 500 msec?
>> This timeout value is the same as  mci_send_cmd:
>> static void 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);
>>          ....
>> }
>>
>> I have not clear that which is suitable.
>> Do you have any suggestion on it?
>>>
>>>> +       do {
>>>> +               if (!dw_mci_card_busy(slot->mmc))
>>>> +                       return;
>>>> +               cpu_relax();
>>>> +       } while (time_before(jiffies, timeout));
>>>> +
>>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>>> +               mci_readl(slot->host, STATUS));
>>>> +
>>>> +       /*
>>>> +        * Data busy, this should not happend when mmc controller send command
>>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>>> +        * should reset controller to avoid getting "Timeout sending command".
>>>> +        */
>>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>>> +
>>> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
>> I have tested on rk3288, if only reset ctroller, data busy bit will not
>> be cleaned,and we will still get
>>
>> "Timeout sending command".
>>
>>>
>>>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>>>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>>>> +}
>>>> +
>>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>   {
>>>>          struct dw_mci *host = slot->host;
>>>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>> +       else
>>>> +               dw_mci_wait_busy(slot);
>>>>
>>> hmm...I would suggest you to call dw_mci_wait_busy() from inside
>>> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
>>> in multiple cases.see [1]
>>>
>>> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
>> I think this patch is more reasonable.
>> So I will resend patches based on this patch.
>> thank you!
>
> I have tested your patches instead [1] above and they do not solve my issue:
> Board: odroid-xu3/exynos5422/dw_mmc_250a.
> MMC card: absent, broken-cd quirk
> SD card: present
>
I doubt $SUBJECT patch in current form can resolve you issue. I have
already given comments on $subject patch.

Can you try out below patch (I have not tested yet) on top of $SUBJECT patch?

=======
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index b0b57e3..ea87844 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -101,6 +101,7 @@ struct idmac_desc {
 #endif /* CONFIG_MMC_DW_IDMAC */

 static int dw_mci_card_busy(struct mmc_host *mmc);
+static void dw_mci_wait_busy(struct dw_mci_slot *slot);
 static bool dw_mci_reset(struct dw_mci *host);
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);

@@ -874,16 +875,22 @@ static void 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);
        unsigned int cmd_status = 0;
+       int re_try = 3; /* just random for now, 1 re-try should be ok */

-       mci_writel(host, CMDARG, arg);
-       wmb();
-       mci_writel(host, CMD, SDMMC_CMD_START | cmd);
+       while(re_try--) {
+               mci_writel(host, CMDARG, arg);
+               wmb();
+               mci_writel(host, CMD, SDMMC_CMD_START | cmd);

-       while (time_before(jiffies, timeout)) {
-               cmd_status = mci_readl(host, CMD);
-               if (!(cmd_status & SDMMC_CMD_START))
-                       return;
+               while (time_before(jiffies, timeout)) {
+                       cmd_status = mci_readl(host, CMD);
+                       if (!(cmd_status & SDMMC_CMD_START))
+                               return;
+               }
+
+               dw_mci_wait_busy(slot);
        }
+
        dev_err(&slot->mmc->class_dev,
                "Timeout sending command (cmd %#x arg %#x status %#x)\n",
                cmd, arg, cmd_status);
@@ -925,8 +932,6 @@ static void dw_mci_setup_bus(struct dw_mci_slot
*slot, bool force_clkinit)
        /* We must continue to set bit 28 in CMD until the change is complete */
        if (host->state == STATE_WAITING_CMD11_DONE)
                sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
-       else
-               dw_mci_wait_busy(slot);

        if (!clock) {
                mci_writel(host, CLKENA, 0);

===== end ======
> System hangs during boot after few minutes kernel spits:
> [  242.188098] INFO: task kworker/u16:1:50 blocked for more than 120
> seconds.
> [  242.193524]       Not tainted
> 3.19.0-next-20150210-00002-gf96831b-dirty #3834
> [  242.200622] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
> disables this message.
> [  242.208422] kworker/u16:1   D c04766ac     0    50      2 0x00000000
> [  242.214756] Workqueue: kmmcd mmc_rescan
> [  242.218553] [<c04766ac>] (__schedule) from [<c0476a58>]
> (schedule+0x34/0x98)
> [  242.225591] [<c0476a58>] (schedule) from [<c047a4dc>]
> (schedule_timeout+0x110/0x164)
> [  242.233302] [<c047a4dc>] (schedule_timeout) from [<c04774f0>]
> (wait_for_common+0xb8/0x14c)
> [  242.241539] [<c04774f0>] (wait_for_common) from [<c0362138>]
> (mmc_wait_for_req+0x68/0x17c)
> [  242.249861] [<c0362138>] (mmc_wait_for_req) from [<c03622cc>]
> (mmc_wait_for_cmd+0x80/0xa0)
> [  242.258002] [<c03622cc>] (mmc_wait_for_cmd) from [<c0367e50>]
> (mmc_go_idle+0x78/0xf8)
> [  242.265796] [<c0367e50>] (mmc_go_idle) from [<c0363e2c>]
> (mmc_rescan+0x280/0x314)
> [  242.273253] [<c0363e2c>] (mmc_rescan) from [<c0034764>]
> (process_one_work+0x120/0x324)
> [  242.281135] [<c0034764>] (process_one_work) from [<c00349cc>]
> (worker_thread+0x30/0x42c)
> [  242.289194] [<c00349cc>] (worker_thread) from [<c003926c>]
> (kthread+0xd8/0xf4)
> [  242.296389] [<c003926c>] (kthread) from [<c000e7c0>]
> (ret_from_fork+0x14/0x34)
>
> Just for record, Exynos4412/dw_mmc_240a with the same configuration
> (no MMC card, broken-cd) works OK without patches.
>
>
> Regards
> Andrzej
>
>>>
>>>>          if (!clock) {
>>>>                  mci_writel(host, CLKENA, 0);
>>>> --
>>>> 1.8.3.2
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> linux-arm-kernel mailing list
>>>> linux-arm-kernel@lists.infradead.org
>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>
>>>
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>



-- 
Regards,
Alim

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-11 23:20           ` Alim Akhtar
@ 2015-02-12  2:28             ` addy ke
  2015-02-12 11:10               ` Andrzej Hajda
  2015-02-12 11:13             ` Andrzej Hajda
  1 sibling, 1 reply; 43+ messages in thread
From: addy ke @ 2015-02-12  2:28 UTC (permalink / raw)
  To: alim.akhtar, a.hajda
  Cc: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders, sonnyrao, amstan, djkurtz, huangtao,
	devicetree, hl, linux-doc, yzq, zyw, zhangqing, linux-mmc,
	linux-kernel, kever.yang

Hi Andrzej and Alim

On 2015/2/12 07:20, Alim Akhtar wrote:
> Hi Andrzej,
> 
> On Wed, Feb 11, 2015 at 5:28 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
>> Hi Alim,
>>
>> On 02/11/2015 03:57 AM, Addy wrote:
>>>
>>> On 2015/02/10 23:22, Alim Akhtar wrote:
>>>> Hi Addy,
>>>>
>>>> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>>> Because of some uncertain factors, such as worse card or worse hardware,
>>>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>>>> will be in busy state. This should not happend when mmc controller
>>>>> send command to update card clocks. If this happends, mci_send_cmd will
>>>>> be failed and we will get 'Timeout sending command', and then system will
>>>>> be blocked. To avoid this, we need reset mmc controller.
>>>>>
>>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>>> ---
>>>>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>>>>   1 file changed, 28 insertions(+)
>>>>>
>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>> index 4d2e3c2..b0b57e3 100644
>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>>>   };
>>>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>>>
>>>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>>
>>>>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>>>                  cmd, arg, cmd_status);
>>>>>   }
>>>>>
>>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>>>> +{
>>>>> +       struct dw_mci *host = slot->host;
>>>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>>>> +
>>>> Why 500 msec?
>>> This timeout value is the same as  mci_send_cmd:
>>> static void 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);
>>>          ....
>>> }
>>>
>>> I have not clear that which is suitable.
>>> Do you have any suggestion on it?
>>>>
>>>>> +       do {
>>>>> +               if (!dw_mci_card_busy(slot->mmc))
>>>>> +                       return;
>>>>> +               cpu_relax();
>>>>> +       } while (time_before(jiffies, timeout));
>>>>> +
>>>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>>>> +               mci_readl(slot->host, STATUS));
>>>>> +
>>>>> +       /*
>>>>> +        * Data busy, this should not happend when mmc controller send command
>>>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>>>> +        * should reset controller to avoid getting "Timeout sending command".
>>>>> +        */
>>>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>>>> +
>>>> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
>>> I have tested on rk3288, if only reset ctroller, data busy bit will not
>>> be cleaned,and we will still get
>>>
>>> "Timeout sending command".
>>>
>>>>
>>>>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>>>>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>>>>> +}
>>>>> +
>>>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>   {
>>>>>          struct dw_mci *host = slot->host;
>>>>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>>> +       else
>>>>> +               dw_mci_wait_busy(slot);
>>>>>
>>>> hmm...I would suggest you to call dw_mci_wait_busy() from inside
>>>> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
>>>> in multiple cases.see [1]
>>>>
>>>> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
>>> I think this patch is more reasonable.
>>> So I will resend patches based on this patch.
>>> thank you!
>>
>> I have tested your patches instead [1] above and they do not solve my issue:
>> Board: odroid-xu3/exynos5422/dw_mmc_250a.
>> MMC card: absent, broken-cd quirk
>> SD card: present
>>
> I doubt $SUBJECT patch in current form can resolve you issue. I have
> already given comments on $subject patch.
> 
> Can you try out below patch (I have not tested yet) on top of $SUBJECT patch?
> 
> =======
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index b0b57e3..ea87844 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -101,6 +101,7 @@ struct idmac_desc {
>  #endif /* CONFIG_MMC_DW_IDMAC */
> 
>  static int dw_mci_card_busy(struct mmc_host *mmc);
> +static void dw_mci_wait_busy(struct dw_mci_slot *slot);
>  static bool dw_mci_reset(struct dw_mci *host);
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
> 
> @@ -874,16 +875,22 @@ static void 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);
>         unsigned int cmd_status = 0;
> +       int re_try = 3; /* just random for now, 1 re-try should be ok */
> 
> -       mci_writel(host, CMDARG, arg);
> -       wmb();
> -       mci_writel(host, CMD, SDMMC_CMD_START | cmd);
> +       while(re_try--) {
> +               mci_writel(host, CMDARG, arg);
> +               wmb();
> +               mci_writel(host, CMD, SDMMC_CMD_START | cmd);
> 
> -       while (time_before(jiffies, timeout)) {
> -               cmd_status = mci_readl(host, CMD);
> -               if (!(cmd_status & SDMMC_CMD_START))
> -                       return;
> +               while (time_before(jiffies, timeout)) {
> +                       cmd_status = mci_readl(host, CMD);
> +                       if (!(cmd_status & SDMMC_CMD_START))
> +                               return;
> +               }
> +
> +               dw_mci_wait_busy(slot);
>         }
> +
>         dev_err(&slot->mmc->class_dev,
>                 "Timeout sending command (cmd %#x arg %#x status %#x)\n",
>                 cmd, arg, cmd_status);
> @@ -925,8 +932,6 @@ static void dw_mci_setup_bus(struct dw_mci_slot
> *slot, bool force_clkinit)
>         /* We must continue to set bit 28 in CMD until the change is complete */
>         if (host->state == STATE_WAITING_CMD11_DONE)
>                 sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
> -       else
> -               dw_mci_wait_busy(slot);
> 
>         if (!clock) {
>                 mci_writel(host, CLKENA, 0);
> 
> ===== end ======
The reason why we are fail to send command is that we got data busy in
none-switch-volt state(host->state != STATE_WAITING_CMD11_DONE).
So:
if(host->state != STATE_WAITING_CMD11_DONE), we must wait until data not busy,
And if (host->state == STATE_WAITING_CMD11_DONE) we should not wait.

>> System hangs during boot after few minutes kernel spits:
>> [  242.188098] INFO: task kworker/u16:1:50 blocked for more than 120
>> seconds.
>> [  242.193524]       Not tainted
>> 3.19.0-next-20150210-00002-gf96831b-dirty #3834
>> [  242.200622] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
>> disables this message.
>> [  242.208422] kworker/u16:1   D c04766ac     0    50      2 0x00000000
>> [  242.214756] Workqueue: kmmcd mmc_rescan
>> [  242.218553] [<c04766ac>] (__schedule) from [<c0476a58>]
>> (schedule+0x34/0x98)
>> [  242.225591] [<c0476a58>] (schedule) from [<c047a4dc>]
>> (schedule_timeout+0x110/0x164)
>> [  242.233302] [<c047a4dc>] (schedule_timeout) from [<c04774f0>]
>> (wait_for_common+0xb8/0x14c)
>> [  242.241539] [<c04774f0>] (wait_for_common) from [<c0362138>]
>> (mmc_wait_for_req+0x68/0x17c)
>> [  242.249861] [<c0362138>] (mmc_wait_for_req) from [<c03622cc>]
>> (mmc_wait_for_cmd+0x80/0xa0)
>> [  242.258002] [<c03622cc>] (mmc_wait_for_cmd) from [<c0367e50>]
>> (mmc_go_idle+0x78/0xf8)
>> [  242.265796] [<c0367e50>] (mmc_go_idle) from [<c0363e2c>]
>> (mmc_rescan+0x280/0x314)
>> [  242.273253] [<c0363e2c>] (mmc_rescan) from [<c0034764>]
>> (process_one_work+0x120/0x324)
>> [  242.281135] [<c0034764>] (process_one_work) from [<c00349cc>]
>> (worker_thread+0x30/0x42c)
>> [  242.289194] [<c00349cc>] (worker_thread) from [<c003926c>]
>> (kthread+0xd8/0xf4)
>> [  242.296389] [<c003926c>] (kthread) from [<c000e7c0>]
>> (ret_from_fork+0x14/0x34)
>>
>> Just for record, Exynos4412/dw_mmc_240a with the same configuration
>> (no MMC card, broken-cd) works OK without patches.
This is because mmc start command,but mmc_request_done() is't called.
I have ever found this issue.
I found that host does't get DTO interrupt when mmc send command to read data.
I have sent a patch for it, see:
https://patchwork.kernel.org/patch/5426531/

Would you please merge it and test again?
>>
>>
>> Regards
>> Andrzej
>>
>>>>
>>>>>          if (!clock) {
>>>>>                  mci_writel(host, CLKENA, 0);
>>>>> --
>>>>> 1.8.3.2
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> linux-arm-kernel mailing list
>>>>> linux-arm-kernel@lists.infradead.org
>>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>>
>>>>
>>>
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>
> 
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-12  2:28             ` addy ke
@ 2015-02-12 11:10               ` Andrzej Hajda
  2015-02-12 13:59                 ` Alim Akhtar
  0 siblings, 1 reply; 43+ messages in thread
From: Andrzej Hajda @ 2015-02-12 11:10 UTC (permalink / raw)
  To: addy ke, alim.akhtar
  Cc: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders, sonnyrao, amstan, djkurtz, huangtao,
	devicetree, hl, linux-doc, yzq, zyw, zhangqing, linux-mmc,
	linux-kernel, kever.yang

On 02/12/2015 03:28 AM, addy ke wrote:
> Hi Andrzej and Alim
>
> On 2015/2/12 07:20, Alim Akhtar wrote:
>> Hi Andrzej,
>>
>> On Wed, Feb 11, 2015 at 5:28 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
>>> Hi Alim,
>>>
>>> On 02/11/2015 03:57 AM, Addy wrote:
>>>> On 2015/02/10 23:22, Alim Akhtar wrote:
>>>>> Hi Addy,
>>>>>
>>>>> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>>>> Because of some uncertain factors, such as worse card or worse hardware,
>>>>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>>>>> will be in busy state. This should not happend when mmc controller
>>>>>> send command to update card clocks. If this happends, mci_send_cmd will
>>>>>> be failed and we will get 'Timeout sending command', and then system will
>>>>>> be blocked. To avoid this, we need reset mmc controller.
>>>>>>
>>>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>>>> ---
>>>>>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>>>>>   1 file changed, 28 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>>> index 4d2e3c2..b0b57e3 100644
>>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>>>>   };
>>>>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>>>>
>>>>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>>>
>>>>>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>>>>                  cmd, arg, cmd_status);
>>>>>>   }
>>>>>>
>>>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>>>>> +{
>>>>>> +       struct dw_mci *host = slot->host;
>>>>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>>>>> +
>>>>> Why 500 msec?
>>>> This timeout value is the same as  mci_send_cmd:
>>>> static void 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);
>>>>          ....
>>>> }
>>>>
>>>> I have not clear that which is suitable.
>>>> Do you have any suggestion on it?
>>>>>> +       do {
>>>>>> +               if (!dw_mci_card_busy(slot->mmc))
>>>>>> +                       return;
>>>>>> +               cpu_relax();
>>>>>> +       } while (time_before(jiffies, timeout));
>>>>>> +
>>>>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>>>>> +               mci_readl(slot->host, STATUS));
>>>>>> +
>>>>>> +       /*
>>>>>> +        * Data busy, this should not happend when mmc controller send command
>>>>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>>>>> +        * should reset controller to avoid getting "Timeout sending command".
>>>>>> +        */
>>>>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>>>>> +
>>>>> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
>>>> I have tested on rk3288, if only reset ctroller, data busy bit will not
>>>> be cleaned,and we will still get
>>>>
>>>> "Timeout sending command".
>>>>
>>>>>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>>>>>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>>>>>> +}
>>>>>> +
>>>>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>>   {
>>>>>>          struct dw_mci *host = slot->host;
>>>>>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>>>> +       else
>>>>>> +               dw_mci_wait_busy(slot);
>>>>>>
>>>>> hmm...I would suggest you to call dw_mci_wait_busy() from inside
>>>>> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
>>>>> in multiple cases.see [1]
>>>>>
>>>>> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
>>>> I think this patch is more reasonable.
>>>> So I will resend patches based on this patch.
>>>> thank you!
>>> I have tested your patches instead [1] above and they do not solve my issue:
>>> Board: odroid-xu3/exynos5422/dw_mmc_250a.
>>> MMC card: absent, broken-cd quirk
>>> SD card: present
>>>
>> I doubt $SUBJECT patch in current form can resolve you issue. I have
>> already given comments on $subject patch.
>>
>> Can you try out below patch (I have not tested yet) on top of $SUBJECT patch?
>>
>> =======
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index b0b57e3..ea87844 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -101,6 +101,7 @@ struct idmac_desc {
>>  #endif /* CONFIG_MMC_DW_IDMAC */
>>
>>  static int dw_mci_card_busy(struct mmc_host *mmc);
>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot);
>>  static bool dw_mci_reset(struct dw_mci *host);
>>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>
>> @@ -874,16 +875,22 @@ static void 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);
>>         unsigned int cmd_status = 0;
>> +       int re_try = 3; /* just random for now, 1 re-try should be ok */
>>
>> -       mci_writel(host, CMDARG, arg);
>> -       wmb();
>> -       mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>> +       while(re_try--) {
>> +               mci_writel(host, CMDARG, arg);
>> +               wmb();
>> +               mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>>
>> -       while (time_before(jiffies, timeout)) {
>> -               cmd_status = mci_readl(host, CMD);
>> -               if (!(cmd_status & SDMMC_CMD_START))
>> -                       return;
>> +               while (time_before(jiffies, timeout)) {
>> +                       cmd_status = mci_readl(host, CMD);
>> +                       if (!(cmd_status & SDMMC_CMD_START))
>> +                               return;
>> +               }
>> +
>> +               dw_mci_wait_busy(slot);
>>         }
>> +
>>         dev_err(&slot->mmc->class_dev,
>>                 "Timeout sending command (cmd %#x arg %#x status %#x)\n",
>>                 cmd, arg, cmd_status);
>> @@ -925,8 +932,6 @@ static void dw_mci_setup_bus(struct dw_mci_slot
>> *slot, bool force_clkinit)
>>         /* We must continue to set bit 28 in CMD until the change is complete */
>>         if (host->state == STATE_WAITING_CMD11_DONE)
>>                 sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>> -       else
>> -               dw_mci_wait_busy(slot);
>>
>>         if (!clock) {
>>                 mci_writel(host, CLKENA, 0);
>>
>> ===== end ======
> The reason why we are fail to send command is that we got data busy in
> none-switch-volt state(host->state != STATE_WAITING_CMD11_DONE).
> So:
> if(host->state != STATE_WAITING_CMD11_DONE), we must wait until data not busy,
> And if (host->state == STATE_WAITING_CMD11_DONE) we should not wait.
>
>>> System hangs during boot after few minutes kernel spits:
>>> [  242.188098] INFO: task kworker/u16:1:50 blocked for more than 120
>>> seconds.
>>> [  242.193524]       Not tainted
>>> 3.19.0-next-20150210-00002-gf96831b-dirty #3834
>>> [  242.200622] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
>>> disables this message.
>>> [  242.208422] kworker/u16:1   D c04766ac     0    50      2 0x00000000
>>> [  242.214756] Workqueue: kmmcd mmc_rescan
>>> [  242.218553] [<c04766ac>] (__schedule) from [<c0476a58>]
>>> (schedule+0x34/0x98)
>>> [  242.225591] [<c0476a58>] (schedule) from [<c047a4dc>]
>>> (schedule_timeout+0x110/0x164)
>>> [  242.233302] [<c047a4dc>] (schedule_timeout) from [<c04774f0>]
>>> (wait_for_common+0xb8/0x14c)
>>> [  242.241539] [<c04774f0>] (wait_for_common) from [<c0362138>]
>>> (mmc_wait_for_req+0x68/0x17c)
>>> [  242.249861] [<c0362138>] (mmc_wait_for_req) from [<c03622cc>]
>>> (mmc_wait_for_cmd+0x80/0xa0)
>>> [  242.258002] [<c03622cc>] (mmc_wait_for_cmd) from [<c0367e50>]
>>> (mmc_go_idle+0x78/0xf8)
>>> [  242.265796] [<c0367e50>] (mmc_go_idle) from [<c0363e2c>]
>>> (mmc_rescan+0x280/0x314)
>>> [  242.273253] [<c0363e2c>] (mmc_rescan) from [<c0034764>]
>>> (process_one_work+0x120/0x324)
>>> [  242.281135] [<c0034764>] (process_one_work) from [<c00349cc>]
>>> (worker_thread+0x30/0x42c)
>>> [  242.289194] [<c00349cc>] (worker_thread) from [<c003926c>]
>>> (kthread+0xd8/0xf4)
>>> [  242.296389] [<c003926c>] (kthread) from [<c000e7c0>]
>>> (ret_from_fork+0x14/0x34)
>>>
>>> Just for record, Exynos4412/dw_mmc_240a with the same configuration
>>> (no MMC card, broken-cd) works OK without patches.
> This is because mmc start command,but mmc_request_done() is't called.
> I have ever found this issue.
> I found that host does't get DTO interrupt when mmc send command to read data.
> I have sent a patch for it, see:
> https://patchwork.kernel.org/patch/5426531/
>
> Would you please merge it and test again?

I have merged it and added quirk to exynos, but it does not help. There
is still timeout:

[  242.188178] INFO: task kworker/u16:1:50 blocked for more than 120
seconds.
[  242.193605]       Not tainted
3.19.0-next-20150212-00003-g7850750-dirty #3841
[  242.200703] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[  242.208592] kworker/u16:1   D c04755f4     0    50      2 0x00000000
[  242.214840] Workqueue: kmmcd mmc_rescan
[  242.218635] [<c04755f4>] (__schedule) from [<c04759a0>]
(schedule+0x34/0x98)
[  242.225671] [<c04759a0>] (schedule) from [<c0479424>]
(schedule_timeout+0x110/0x164)
[  242.233383] [<c0479424>] (schedule_timeout) from [<c0476438>]
(wait_for_common+0xb8/0x14c)
[  242.241619] [<c0476438>] (wait_for_common) from [<c0361600>]
(mmc_wait_for_req+0xb0/0x13c)
[  242.249848] [<c0361600>] (mmc_wait_for_req) from [<c036170c>]
(mmc_wait_for_cmd+0x80/0xa0)
[  242.258086] [<c036170c>] (mmc_wait_for_cmd) from [<c03676e0>]
(mmc_go_idle+0x78/0xf8)
[  242.265876] [<c03676e0>] (mmc_go_idle) from [<c0363700>]
(mmc_rescan+0x25c/0x2e4)
[  242.273333] [<c0363700>] (mmc_rescan) from [<c0034764>]
(process_one_work+0x120/0x324)
[  242.281216] [<c0034764>] (process_one_work) from [<c00349cc>]
(worker_thread+0x30/0x42c)
[  242.289275] [<c00349cc>] (worker_thread) from [<c003926c>]
(kthread+0xd8/0xf4)
[  242.296469] [<c003926c>] (kthread) from [<c000e7c0>]
(ret_from_fork+0x14/0x34)


Regards
Andrzej

>>>
>>> Regards
>>> Andrzej
>>>
>>>>>>          if (!clock) {
>>>>>>                  mci_writel(host, CLKENA, 0);
>>>>>> --
>>>>>> 1.8.3.2
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> linux-arm-kernel mailing list
>>>>>> linux-arm-kernel@lists.infradead.org
>>>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>>>
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>
>>
>>
>


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-11 23:20           ` Alim Akhtar
  2015-02-12  2:28             ` addy ke
@ 2015-02-12 11:13             ` Andrzej Hajda
  2015-02-12 13:53               ` Alim Akhtar
  1 sibling, 1 reply; 43+ messages in thread
From: Andrzej Hajda @ 2015-02-12 11:13 UTC (permalink / raw)
  To: Alim Akhtar
  Cc: Addy, robh+dt, pawel.moll, Mark Rutland, ijc+devicetree,
	Kumar Gala, rdunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Ulf Hansson, dinguyen, Heiko Stübner, Olof Johansson,
	Douglas Anderson, Sonny Rao, Alexandru Stan, Daniel Kurtz,
	Tao Huang, devicetree, Lin Huang, linux-doc,
	姚智情,
	Chris Zhong, zhangqing, linux-mmc, linux-kernel, Kever Yang

On 02/12/2015 12:20 AM, Alim Akhtar wrote:
> Hi Andrzej,
>
> On Wed, Feb 11, 2015 at 5:28 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
>> Hi Alim,
>>
>> On 02/11/2015 03:57 AM, Addy wrote:
>>> On 2015/02/10 23:22, Alim Akhtar wrote:
>>>> Hi Addy,
>>>>
>>>> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>>> Because of some uncertain factors, such as worse card or worse hardware,
>>>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>>>> will be in busy state. This should not happend when mmc controller
>>>>> send command to update card clocks. If this happends, mci_send_cmd will
>>>>> be failed and we will get 'Timeout sending command', and then system will
>>>>> be blocked. To avoid this, we need reset mmc controller.
>>>>>
>>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>>> ---
>>>>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>>>>   1 file changed, 28 insertions(+)
>>>>>
>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>> index 4d2e3c2..b0b57e3 100644
>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>>>   };
>>>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>>>
>>>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>>
>>>>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>>>                  cmd, arg, cmd_status);
>>>>>   }
>>>>>
>>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>>>> +{
>>>>> +       struct dw_mci *host = slot->host;
>>>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>>>> +
>>>> Why 500 msec?
>>> This timeout value is the same as  mci_send_cmd:
>>> static void 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);
>>>          ....
>>> }
>>>
>>> I have not clear that which is suitable.
>>> Do you have any suggestion on it?
>>>>> +       do {
>>>>> +               if (!dw_mci_card_busy(slot->mmc))
>>>>> +                       return;
>>>>> +               cpu_relax();
>>>>> +       } while (time_before(jiffies, timeout));
>>>>> +
>>>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>>>> +               mci_readl(slot->host, STATUS));
>>>>> +
>>>>> +       /*
>>>>> +        * Data busy, this should not happend when mmc controller send command
>>>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>>>> +        * should reset controller to avoid getting "Timeout sending command".
>>>>> +        */
>>>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>>>> +
>>>> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
>>> I have tested on rk3288, if only reset ctroller, data busy bit will not
>>> be cleaned,and we will still get
>>>
>>> "Timeout sending command".
>>>
>>>>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>>>>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>>>>> +}
>>>>> +
>>>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>   {
>>>>>          struct dw_mci *host = slot->host;
>>>>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>>> +       else
>>>>> +               dw_mci_wait_busy(slot);
>>>>>
>>>> hmm...I would suggest you to call dw_mci_wait_busy() from inside
>>>> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
>>>> in multiple cases.see [1]
>>>>
>>>> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
>>> I think this patch is more reasonable.
>>> So I will resend patches based on this patch.
>>> thank you!
>> I have tested your patches instead [1] above and they do not solve my issue:
>> Board: odroid-xu3/exynos5422/dw_mmc_250a.
>> MMC card: absent, broken-cd quirk
>> SD card: present
>>
> I doubt $SUBJECT patch in current form can resolve you issue. I have
> already given comments on $subject patch.
>
> Can you try out below patch (I have not tested yet) on top of $SUBJECT patch?
>
> =======
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index b0b57e3..ea87844 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -101,6 +101,7 @@ struct idmac_desc {
>  #endif /* CONFIG_MMC_DW_IDMAC */
>
>  static int dw_mci_card_busy(struct mmc_host *mmc);
> +static void dw_mci_wait_busy(struct dw_mci_slot *slot);
>  static bool dw_mci_reset(struct dw_mci *host);
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>
> @@ -874,16 +875,22 @@ static void 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);
>         unsigned int cmd_status = 0;
> +       int re_try = 3; /* just random for now, 1 re-try should be ok */
>
> -       mci_writel(host, CMDARG, arg);
> -       wmb();
> -       mci_writel(host, CMD, SDMMC_CMD_START | cmd);
> +       while(re_try--) {
> +               mci_writel(host, CMDARG, arg);
> +               wmb();
> +               mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>
> -       while (time_before(jiffies, timeout)) {
> -               cmd_status = mci_readl(host, CMD);
> -               if (!(cmd_status & SDMMC_CMD_START))
> -                       return;
> +               while (time_before(jiffies, timeout)) {
> +                       cmd_status = mci_readl(host, CMD);
> +                       if (!(cmd_status & SDMMC_CMD_START))
> +                               return;
> +               }
> +
> +               dw_mci_wait_busy(slot);
>         }
> +
>         dev_err(&slot->mmc->class_dev,
>                 "Timeout sending command (cmd %#x arg %#x status %#x)\n",
>                 cmd, arg, cmd_status);
> @@ -925,8 +932,6 @@ static void dw_mci_setup_bus(struct dw_mci_slot
> *slot, bool force_clkinit)
>         /* We must continue to set bit 28 in CMD until the change is complete */
>         if (host->state == STATE_WAITING_CMD11_DONE)
>                 sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
> -       else
> -               dw_mci_wait_busy(slot);
>
>         if (!clock) {
>                 mci_writel(host, CLKENA, 0);

It does not help, there is still the same timeout.

Regards
Andrzej

>
> ===== end ======
>> System hangs during boot after few minutes kernel spits:
>> [  242.188098] INFO: task kworker/u16:1:50 blocked for more than 120
>> seconds.
>> [  242.193524]       Not tainted
>> 3.19.0-next-20150210-00002-gf96831b-dirty #3834
>> [  242.200622] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
>> disables this message.
>> [  242.208422] kworker/u16:1   D c04766ac     0    50      2 0x00000000
>> [  242.214756] Workqueue: kmmcd mmc_rescan
>> [  242.218553] [<c04766ac>] (__schedule) from [<c0476a58>]
>> (schedule+0x34/0x98)
>> [  242.225591] [<c0476a58>] (schedule) from [<c047a4dc>]
>> (schedule_timeout+0x110/0x164)
>> [  242.233302] [<c047a4dc>] (schedule_timeout) from [<c04774f0>]
>> (wait_for_common+0xb8/0x14c)
>> [  242.241539] [<c04774f0>] (wait_for_common) from [<c0362138>]
>> (mmc_wait_for_req+0x68/0x17c)
>> [  242.249861] [<c0362138>] (mmc_wait_for_req) from [<c03622cc>]
>> (mmc_wait_for_cmd+0x80/0xa0)
>> [  242.258002] [<c03622cc>] (mmc_wait_for_cmd) from [<c0367e50>]
>> (mmc_go_idle+0x78/0xf8)
>> [  242.265796] [<c0367e50>] (mmc_go_idle) from [<c0363e2c>]
>> (mmc_rescan+0x280/0x314)
>> [  242.273253] [<c0363e2c>] (mmc_rescan) from [<c0034764>]
>> (process_one_work+0x120/0x324)
>> [  242.281135] [<c0034764>] (process_one_work) from [<c00349cc>]
>> (worker_thread+0x30/0x42c)
>> [  242.289194] [<c00349cc>] (worker_thread) from [<c003926c>]
>> (kthread+0xd8/0xf4)
>> [  242.296389] [<c003926c>] (kthread) from [<c000e7c0>]
>> (ret_from_fork+0x14/0x34)
>>
>> Just for record, Exynos4412/dw_mmc_240a with the same configuration
>> (no MMC card, broken-cd) works OK without patches.
>>
>>
>> Regards
>> Andrzej
>>
>>>>>          if (!clock) {
>>>>>                  mci_writel(host, CLKENA, 0);
>>>>> --
>>>>> 1.8.3.2
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> linux-arm-kernel mailing list
>>>>> linux-arm-kernel@lists.infradead.org
>>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>>
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>
>


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-12 11:13             ` Andrzej Hajda
@ 2015-02-12 13:53               ` Alim Akhtar
  0 siblings, 0 replies; 43+ messages in thread
From: Alim Akhtar @ 2015-02-12 13:53 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: Addy, robh+dt, pawel.moll, Mark Rutland, ijc+devicetree,
	Kumar Gala, rdunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Ulf Hansson, dinguyen, Heiko Stübner, Olof Johansson,
	Douglas Anderson, Sonny Rao, Alexandru Stan, Daniel Kurtz,
	Tao Huang, devicetree, Lin Huang, linux-doc,
	姚智情,
	Chris Zhong, zhangqing, linux-mmc, linux-kernel, Kever Yang

Hi Andrzej,

On Thu, Feb 12, 2015 at 4:43 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
> On 02/12/2015 12:20 AM, Alim Akhtar wrote:
>> Hi Andrzej,
>>
>> On Wed, Feb 11, 2015 at 5:28 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
>>> Hi Alim,
>>>
>>> On 02/11/2015 03:57 AM, Addy wrote:
>>>> On 2015/02/10 23:22, Alim Akhtar wrote:
>>>>> Hi Addy,
>>>>>
>>>>> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>>>> Because of some uncertain factors, such as worse card or worse hardware,
>>>>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>>>>> will be in busy state. This should not happend when mmc controller
>>>>>> send command to update card clocks. If this happends, mci_send_cmd will
>>>>>> be failed and we will get 'Timeout sending command', and then system will
>>>>>> be blocked. To avoid this, we need reset mmc controller.
>>>>>>
>>>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>>>> ---
>>>>>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>>>>>   1 file changed, 28 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>>> index 4d2e3c2..b0b57e3 100644
>>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>>>>   };
>>>>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>>>>
>>>>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>>>
>>>>>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>>>>                  cmd, arg, cmd_status);
>>>>>>   }
>>>>>>
>>>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>>>>> +{
>>>>>> +       struct dw_mci *host = slot->host;
>>>>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>>>>> +
>>>>> Why 500 msec?
>>>> This timeout value is the same as  mci_send_cmd:
>>>> static void 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);
>>>>          ....
>>>> }
>>>>
>>>> I have not clear that which is suitable.
>>>> Do you have any suggestion on it?
>>>>>> +       do {
>>>>>> +               if (!dw_mci_card_busy(slot->mmc))
>>>>>> +                       return;
>>>>>> +               cpu_relax();
>>>>>> +       } while (time_before(jiffies, timeout));
>>>>>> +
>>>>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>>>>> +               mci_readl(slot->host, STATUS));
>>>>>> +
>>>>>> +       /*
>>>>>> +        * Data busy, this should not happend when mmc controller send command
>>>>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>>>>> +        * should reset controller to avoid getting "Timeout sending command".
>>>>>> +        */
>>>>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>>>>> +
>>>>> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
>>>> I have tested on rk3288, if only reset ctroller, data busy bit will not
>>>> be cleaned,and we will still get
>>>>
>>>> "Timeout sending command".
>>>>
>>>>>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>>>>>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>>>>>> +}
>>>>>> +
>>>>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>>   {
>>>>>>          struct dw_mci *host = slot->host;
>>>>>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>>>> +       else
>>>>>> +               dw_mci_wait_busy(slot);
>>>>>>
>>>>> hmm...I would suggest you to call dw_mci_wait_busy() from inside
>>>>> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
>>>>> in multiple cases.see [1]
>>>>>
>>>>> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
>>>> I think this patch is more reasonable.
>>>> So I will resend patches based on this patch.
>>>> thank you!
>>> I have tested your patches instead [1] above and they do not solve my issue:
>>> Board: odroid-xu3/exynos5422/dw_mmc_250a.
>>> MMC card: absent, broken-cd quirk
>>> SD card: present
>>>
>> I doubt $SUBJECT patch in current form can resolve you issue. I have
>> already given comments on $subject patch.
>>
>> Can you try out below patch (I have not tested yet) on top of $SUBJECT patch?
>>
>> =======
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index b0b57e3..ea87844 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -101,6 +101,7 @@ struct idmac_desc {
>>  #endif /* CONFIG_MMC_DW_IDMAC */
>>
>>  static int dw_mci_card_busy(struct mmc_host *mmc);
>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot);
>>  static bool dw_mci_reset(struct dw_mci *host);
>>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>
>> @@ -874,16 +875,22 @@ static void 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);
>>         unsigned int cmd_status = 0;
>> +       int re_try = 3; /* just random for now, 1 re-try should be ok */
>>
>> -       mci_writel(host, CMDARG, arg);
>> -       wmb();
>> -       mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>> +       while(re_try--) {
>> +               mci_writel(host, CMDARG, arg);
>> +               wmb();
>> +               mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>>
>> -       while (time_before(jiffies, timeout)) {
>> -               cmd_status = mci_readl(host, CMD);
>> -               if (!(cmd_status & SDMMC_CMD_START))
>> -                       return;
>> +               while (time_before(jiffies, timeout)) {
>> +                       cmd_status = mci_readl(host, CMD);
>> +                       if (!(cmd_status & SDMMC_CMD_START))
>> +                               return;
>> +               }
>> +
>> +               dw_mci_wait_busy(slot);
>>         }
>> +
>>         dev_err(&slot->mmc->class_dev,
>>                 "Timeout sending command (cmd %#x arg %#x status %#x)\n",
>>                 cmd, arg, cmd_status);
>> @@ -925,8 +932,6 @@ static void dw_mci_setup_bus(struct dw_mci_slot
>> *slot, bool force_clkinit)
>>         /* We must continue to set bit 28 in CMD until the change is complete */
>>         if (host->state == STATE_WAITING_CMD11_DONE)
>>                 sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>> -       else
>> -               dw_mci_wait_busy(slot);
>>
>>         if (!clock) {
>>                 mci_writel(host, CLKENA, 0);
>
> It does not help, there is still the same timeout.
>
Did you tried this on top of the original $subject patch?
What does STATUS register tells? Can you post the full log here?

> Regards
> Andrzej
>
>>
>> ===== end ======
>>> System hangs during boot after few minutes kernel spits:
>>> [  242.188098] INFO: task kworker/u16:1:50 blocked for more than 120
>>> seconds.
>>> [  242.193524]       Not tainted
>>> 3.19.0-next-20150210-00002-gf96831b-dirty #3834
>>> [  242.200622] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
>>> disables this message.
>>> [  242.208422] kworker/u16:1   D c04766ac     0    50      2 0x00000000
>>> [  242.214756] Workqueue: kmmcd mmc_rescan
>>> [  242.218553] [<c04766ac>] (__schedule) from [<c0476a58>]
>>> (schedule+0x34/0x98)
>>> [  242.225591] [<c0476a58>] (schedule) from [<c047a4dc>]
>>> (schedule_timeout+0x110/0x164)
>>> [  242.233302] [<c047a4dc>] (schedule_timeout) from [<c04774f0>]
>>> (wait_for_common+0xb8/0x14c)
>>> [  242.241539] [<c04774f0>] (wait_for_common) from [<c0362138>]
>>> (mmc_wait_for_req+0x68/0x17c)
>>> [  242.249861] [<c0362138>] (mmc_wait_for_req) from [<c03622cc>]
>>> (mmc_wait_for_cmd+0x80/0xa0)
>>> [  242.258002] [<c03622cc>] (mmc_wait_for_cmd) from [<c0367e50>]
>>> (mmc_go_idle+0x78/0xf8)
>>> [  242.265796] [<c0367e50>] (mmc_go_idle) from [<c0363e2c>]
>>> (mmc_rescan+0x280/0x314)
>>> [  242.273253] [<c0363e2c>] (mmc_rescan) from [<c0034764>]
>>> (process_one_work+0x120/0x324)
>>> [  242.281135] [<c0034764>] (process_one_work) from [<c00349cc>]
>>> (worker_thread+0x30/0x42c)
>>> [  242.289194] [<c00349cc>] (worker_thread) from [<c003926c>]
>>> (kthread+0xd8/0xf4)
>>> [  242.296389] [<c003926c>] (kthread) from [<c000e7c0>]
>>> (ret_from_fork+0x14/0x34)
>>>
>>> Just for record, Exynos4412/dw_mmc_240a with the same configuration
>>> (no MMC card, broken-cd) works OK without patches.
>>>
>>>
>>> Regards
>>> Andrzej
>>>
>>>>>>          if (!clock) {
>>>>>>                  mci_writel(host, CLKENA, 0);
>>>>>> --
>>>>>> 1.8.3.2
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> linux-arm-kernel mailing list
>>>>>> linux-arm-kernel@lists.infradead.org
>>>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>>>
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>
>>
>>
>



-- 
Regards,
Alim

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-12 11:10               ` Andrzej Hajda
@ 2015-02-12 13:59                 ` Alim Akhtar
  2015-02-13  8:15                   ` addy ke
  0 siblings, 1 reply; 43+ messages in thread
From: Alim Akhtar @ 2015-02-12 13:59 UTC (permalink / raw)
  To: Andrzej Hajda
  Cc: addy ke, robh+dt, pawel.moll, Mark Rutland, ijc+devicetree,
	Kumar Gala, rdunlap, Seungwon Jeon, Jaehoon Chung, Chris Ball,
	Ulf Hansson, dinguyen, Heiko Stübner, Olof Johansson,
	Douglas Anderson, Sonny Rao, Alexandru Stan, Daniel Kurtz,
	Tao Huang, devicetree, Lin Huang, linux-doc,
	姚智情,
	Chris Zhong, zhangqing, linux-mmc, linux-kernel, Kever Yang

On Thu, Feb 12, 2015 at 4:40 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
> On 02/12/2015 03:28 AM, addy ke wrote:
>> Hi Andrzej and Alim
>>
>> On 2015/2/12 07:20, Alim Akhtar wrote:
>>> Hi Andrzej,
>>>
>>> On Wed, Feb 11, 2015 at 5:28 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
>>>> Hi Alim,
>>>>
>>>> On 02/11/2015 03:57 AM, Addy wrote:
>>>>> On 2015/02/10 23:22, Alim Akhtar wrote:
>>>>>> Hi Addy,
>>>>>>
>>>>>> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>>>>> Because of some uncertain factors, such as worse card or worse hardware,
>>>>>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>>>>>> will be in busy state. This should not happend when mmc controller
>>>>>>> send command to update card clocks. If this happends, mci_send_cmd will
>>>>>>> be failed and we will get 'Timeout sending command', and then system will
>>>>>>> be blocked. To avoid this, we need reset mmc controller.
>>>>>>>
>>>>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>>>>> ---
>>>>>>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>>>>>>   1 file changed, 28 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>>>> index 4d2e3c2..b0b57e3 100644
>>>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>>>>>   };
>>>>>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>>>>>
>>>>>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>>>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>>>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>>>>
>>>>>>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>>>>>                  cmd, arg, cmd_status);
>>>>>>>   }
>>>>>>>
>>>>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>>>>>> +{
>>>>>>> +       struct dw_mci *host = slot->host;
>>>>>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>>>>>> +
>>>>>> Why 500 msec?
>>>>> This timeout value is the same as  mci_send_cmd:
>>>>> static void 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);
>>>>>          ....
>>>>> }
>>>>>
>>>>> I have not clear that which is suitable.
>>>>> Do you have any suggestion on it?
>>>>>>> +       do {
>>>>>>> +               if (!dw_mci_card_busy(slot->mmc))
>>>>>>> +                       return;
>>>>>>> +               cpu_relax();
>>>>>>> +       } while (time_before(jiffies, timeout));
>>>>>>> +
>>>>>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>>>>>> +               mci_readl(slot->host, STATUS));
>>>>>>> +
>>>>>>> +       /*
>>>>>>> +        * Data busy, this should not happend when mmc controller send command
>>>>>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>>>>>> +        * should reset controller to avoid getting "Timeout sending command".
>>>>>>> +        */
>>>>>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>>>>>> +
>>>>>> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
>>>>> I have tested on rk3288, if only reset ctroller, data busy bit will not
>>>>> be cleaned,and we will still get
>>>>>
>>>>> "Timeout sending command".
>>>>>
>>>>>>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>>>>>>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>>>>>>> +}
>>>>>>> +
>>>>>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>>>   {
>>>>>>>          struct dw_mci *host = slot->host;
>>>>>>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>>>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>>>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>>>>> +       else
>>>>>>> +               dw_mci_wait_busy(slot);
>>>>>>>
>>>>>> hmm...I would suggest you to call dw_mci_wait_busy() from inside
>>>>>> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
>>>>>> in multiple cases.see [1]
>>>>>>
>>>>>> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
>>>>> I think this patch is more reasonable.
>>>>> So I will resend patches based on this patch.
>>>>> thank you!
>>>> I have tested your patches instead [1] above and they do not solve my issue:
>>>> Board: odroid-xu3/exynos5422/dw_mmc_250a.
>>>> MMC card: absent, broken-cd quirk
>>>> SD card: present
>>>>
>>> I doubt $SUBJECT patch in current form can resolve you issue. I have
>>> already given comments on $subject patch.
>>>
>>> Can you try out below patch (I have not tested yet) on top of $SUBJECT patch?
>>>
>>> =======
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index b0b57e3..ea87844 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -101,6 +101,7 @@ struct idmac_desc {
>>>  #endif /* CONFIG_MMC_DW_IDMAC */
>>>
>>>  static int dw_mci_card_busy(struct mmc_host *mmc);
>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot);
>>>  static bool dw_mci_reset(struct dw_mci *host);
>>>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>
>>> @@ -874,16 +875,22 @@ static void 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);
>>>         unsigned int cmd_status = 0;
>>> +       int re_try = 3; /* just random for now, 1 re-try should be ok */
>>>
>>> -       mci_writel(host, CMDARG, arg);
>>> -       wmb();
>>> -       mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>>> +       while(re_try--) {
>>> +               mci_writel(host, CMDARG, arg);
>>> +               wmb();
>>> +               mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>>>
>>> -       while (time_before(jiffies, timeout)) {
>>> -               cmd_status = mci_readl(host, CMD);
>>> -               if (!(cmd_status & SDMMC_CMD_START))
>>> -                       return;
>>> +               while (time_before(jiffies, timeout)) {
>>> +                       cmd_status = mci_readl(host, CMD);
>>> +                       if (!(cmd_status & SDMMC_CMD_START))
>>> +                               return;
>>> +               }
>>> +
>>> +               dw_mci_wait_busy(slot);
>>>         }
>>> +
>>>         dev_err(&slot->mmc->class_dev,
>>>                 "Timeout sending command (cmd %#x arg %#x status %#x)\n",
>>>                 cmd, arg, cmd_status);
>>> @@ -925,8 +932,6 @@ static void dw_mci_setup_bus(struct dw_mci_slot
>>> *slot, bool force_clkinit)
>>>         /* We must continue to set bit 28 in CMD until the change is complete */
>>>         if (host->state == STATE_WAITING_CMD11_DONE)
>>>                 sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>> -       else
>>> -               dw_mci_wait_busy(slot);
>>>
>>>         if (!clock) {
>>>                 mci_writel(host, CLKENA, 0);
>>>
>>> ===== end ======
>> The reason why we are fail to send command is that we got data busy in
>> none-switch-volt state(host->state != STATE_WAITING_CMD11_DONE).
>> So:
>> if(host->state != STATE_WAITING_CMD11_DONE), we must wait until data not busy,
>> And if (host->state == STATE_WAITING_CMD11_DONE) we should not wait.
>>
>>>> System hangs during boot after few minutes kernel spits:
>>>> [  242.188098] INFO: task kworker/u16:1:50 blocked for more than 120
>>>> seconds.
>>>> [  242.193524]       Not tainted
>>>> 3.19.0-next-20150210-00002-gf96831b-dirty #3834
>>>> [  242.200622] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
>>>> disables this message.
>>>> [  242.208422] kworker/u16:1   D c04766ac     0    50      2 0x00000000
>>>> [  242.214756] Workqueue: kmmcd mmc_rescan
>>>> [  242.218553] [<c04766ac>] (__schedule) from [<c0476a58>]
>>>> (schedule+0x34/0x98)
>>>> [  242.225591] [<c0476a58>] (schedule) from [<c047a4dc>]
>>>> (schedule_timeout+0x110/0x164)
>>>> [  242.233302] [<c047a4dc>] (schedule_timeout) from [<c04774f0>]
>>>> (wait_for_common+0xb8/0x14c)
>>>> [  242.241539] [<c04774f0>] (wait_for_common) from [<c0362138>]
>>>> (mmc_wait_for_req+0x68/0x17c)
>>>> [  242.249861] [<c0362138>] (mmc_wait_for_req) from [<c03622cc>]
>>>> (mmc_wait_for_cmd+0x80/0xa0)
>>>> [  242.258002] [<c03622cc>] (mmc_wait_for_cmd) from [<c0367e50>]
>>>> (mmc_go_idle+0x78/0xf8)
>>>> [  242.265796] [<c0367e50>] (mmc_go_idle) from [<c0363e2c>]
>>>> (mmc_rescan+0x280/0x314)
>>>> [  242.273253] [<c0363e2c>] (mmc_rescan) from [<c0034764>]
>>>> (process_one_work+0x120/0x324)
>>>> [  242.281135] [<c0034764>] (process_one_work) from [<c00349cc>]
>>>> (worker_thread+0x30/0x42c)
>>>> [  242.289194] [<c00349cc>] (worker_thread) from [<c003926c>]
>>>> (kthread+0xd8/0xf4)
>>>> [  242.296389] [<c003926c>] (kthread) from [<c000e7c0>]
>>>> (ret_from_fork+0x14/0x34)
>>>>
>>>> Just for record, Exynos4412/dw_mmc_240a with the same configuration
>>>> (no MMC card, broken-cd) works OK without patches.
>> This is because mmc start command,but mmc_request_done() is't called.
>> I have ever found this issue.
>> I found that host does't get DTO interrupt when mmc send command to read data.
>> I have sent a patch for it, see:
>> https://patchwork.kernel.org/patch/5426531/
>>
>> Would you please merge it and test again?
>
> I have merged it and added quirk to exynos, but it does not help. There
> is still timeout:
>
I don't think this DTO issue. I think we need a way to reproduce this,
at least on Exyons5422/5800.
what type of sd card is being used? Are you trying UHS-I mode by any chance?

> [  242.188178] INFO: task kworker/u16:1:50 blocked for more than 120
> seconds.
> [  242.193605]       Not tainted
> 3.19.0-next-20150212-00003-g7850750-dirty #3841
> [  242.200703] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
> disables this message.
> [  242.208592] kworker/u16:1   D c04755f4     0    50      2 0x00000000
> [  242.214840] Workqueue: kmmcd mmc_rescan
> [  242.218635] [<c04755f4>] (__schedule) from [<c04759a0>]
> (schedule+0x34/0x98)
> [  242.225671] [<c04759a0>] (schedule) from [<c0479424>]
> (schedule_timeout+0x110/0x164)
> [  242.233383] [<c0479424>] (schedule_timeout) from [<c0476438>]
> (wait_for_common+0xb8/0x14c)
> [  242.241619] [<c0476438>] (wait_for_common) from [<c0361600>]
> (mmc_wait_for_req+0xb0/0x13c)
> [  242.249848] [<c0361600>] (mmc_wait_for_req) from [<c036170c>]
> (mmc_wait_for_cmd+0x80/0xa0)
> [  242.258086] [<c036170c>] (mmc_wait_for_cmd) from [<c03676e0>]
> (mmc_go_idle+0x78/0xf8)
> [  242.265876] [<c03676e0>] (mmc_go_idle) from [<c0363700>]
> (mmc_rescan+0x25c/0x2e4)
> [  242.273333] [<c0363700>] (mmc_rescan) from [<c0034764>]
> (process_one_work+0x120/0x324)
> [  242.281216] [<c0034764>] (process_one_work) from [<c00349cc>]
> (worker_thread+0x30/0x42c)
> [  242.289275] [<c00349cc>] (worker_thread) from [<c003926c>]
> (kthread+0xd8/0xf4)
> [  242.296469] [<c003926c>] (kthread) from [<c000e7c0>]
> (ret_from_fork+0x14/0x34)
>
>
> Regards
> Andrzej
>
>>>>
>>>> Regards
>>>> Andrzej
>>>>
>>>>>>>          if (!clock) {
>>>>>>>                  mci_writel(host, CLKENA, 0);
>>>>>>> --
>>>>>>> 1.8.3.2
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> linux-arm-kernel mailing list
>>>>>>> linux-arm-kernel@lists.infradead.org
>>>>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>>>>
>>>>>
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>
>>>
>>>
>>
>



-- 
Regards,
Alim

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-12 13:59                 ` Alim Akhtar
@ 2015-02-13  8:15                   ` addy ke
  0 siblings, 0 replies; 43+ messages in thread
From: addy ke @ 2015-02-13  8:15 UTC (permalink / raw)
  To: alim.akhtar, a.hajda
  Cc: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	rdunlap, tgih.jun, jh80.chung, chris, ulf.hansson, dinguyen,
	heiko, olof, dianders, sonnyrao, amstan, djkurtz, huangtao,
	devicetree, hl, linux-doc, yzq, zyw, zhangqing, linux-mmc,
	linux-kernel, kever.yang



On 2015/2/12 21:59, Alim Akhtar wrote:
> On Thu, Feb 12, 2015 at 4:40 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
>> On 02/12/2015 03:28 AM, addy ke wrote:
>>> Hi Andrzej and Alim
>>>
>>> On 2015/2/12 07:20, Alim Akhtar wrote:
>>>> Hi Andrzej,
>>>>
>>>> On Wed, Feb 11, 2015 at 5:28 PM, Andrzej Hajda <a.hajda@samsung.com> wrote:
>>>>> Hi Alim,
>>>>>
>>>>> On 02/11/2015 03:57 AM, Addy wrote:
>>>>>> On 2015/02/10 23:22, Alim Akhtar wrote:
>>>>>>> Hi Addy,
>>>>>>>
>>>>>>> On Mon, Feb 9, 2015 at 12:55 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>>>>>> Because of some uncertain factors, such as worse card or worse hardware,
>>>>>>>> DAT[3:0](the data lines) may be pulled down by card, and mmc controller
>>>>>>>> will be in busy state. This should not happend when mmc controller
>>>>>>>> send command to update card clocks. If this happends, mci_send_cmd will
>>>>>>>> be failed and we will get 'Timeout sending command', and then system will
>>>>>>>> be blocked. To avoid this, we need reset mmc controller.
>>>>>>>>
>>>>>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>>>>>> ---
>>>>>>>>   drivers/mmc/host/dw_mmc.c | 28 ++++++++++++++++++++++++++++
>>>>>>>>   1 file changed, 28 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>>>>> index 4d2e3c2..b0b57e3 100644
>>>>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>>>>> @@ -100,6 +100,7 @@ struct idmac_desc {
>>>>>>>>   };
>>>>>>>>   #endif /* CONFIG_MMC_DW_IDMAC */
>>>>>>>>
>>>>>>>> +static int dw_mci_card_busy(struct mmc_host *mmc);
>>>>>>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>>>>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>>>>>
>>>>>>>> @@ -888,6 +889,31 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
>>>>>>>>                  cmd, arg, cmd_status);
>>>>>>>>   }
>>>>>>>>
>>>>>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot)
>>>>>>>> +{
>>>>>>>> +       struct dw_mci *host = slot->host;
>>>>>>>> +       unsigned long timeout = jiffies + msecs_to_jiffies(500);
>>>>>>>> +
>>>>>>> Why 500 msec?
>>>>>> This timeout value is the same as  mci_send_cmd:
>>>>>> static void 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);
>>>>>>          ....
>>>>>> }
>>>>>>
>>>>>> I have not clear that which is suitable.
>>>>>> Do you have any suggestion on it?
>>>>>>>> +       do {
>>>>>>>> +               if (!dw_mci_card_busy(slot->mmc))
>>>>>>>> +                       return;
>>>>>>>> +               cpu_relax();
>>>>>>>> +       } while (time_before(jiffies, timeout));
>>>>>>>> +
>>>>>>>> +       dev_err(host->dev, "Data busy (status %#x)\n",
>>>>>>>> +               mci_readl(slot->host, STATUS));
>>>>>>>> +
>>>>>>>> +       /*
>>>>>>>> +        * Data busy, this should not happend when mmc controller send command
>>>>>>>> +        * to update card clocks in non-volt-switch state. If it happends, we
>>>>>>>> +        * should reset controller to avoid getting "Timeout sending command".
>>>>>>>> +        */
>>>>>>>> +       dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
>>>>>>>> +
>>>>>>> Why you need to reset all blocks? may be CTRL_RESET is good enough here.
>>>>>> I have tested on rk3288, if only reset ctroller, data busy bit will not
>>>>>> be cleaned,and we will still get
>>>>>>
>>>>>> "Timeout sending command".
>>>>>>
>>>>>>>> +       /* Fail to reset controller or still data busy, WARN_ON! */
>>>>>>>> +       WARN_ON(dw_mci_card_busy(slot->mmc));
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>   static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>>>>   {
>>>>>>>>          struct dw_mci *host = slot->host;
>>>>>>>> @@ -899,6 +925,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
>>>>>>>>          /* We must continue to set bit 28 in CMD until the change is complete */
>>>>>>>>          if (host->state == STATE_WAITING_CMD11_DONE)
>>>>>>>>                  sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>>>>>> +       else
>>>>>>>> +               dw_mci_wait_busy(slot);
>>>>>>>>
>>>>>>> hmm...I would suggest you to call dw_mci_wait_busy() from inside
>>>>>>> mci_send_cmd(), seems like dw_mmc hangs while sending update clock cmd
>>>>>>> in multiple cases.see [1]
>>>>>>>
>>>>>>> [1]: http://permalink.gmane.org/gmane.linux.kernel.mmc/31140
>>>>>> I think this patch is more reasonable.
>>>>>> So I will resend patches based on this patch.
>>>>>> thank you!
>>>>> I have tested your patches instead [1] above and they do not solve my issue:
>>>>> Board: odroid-xu3/exynos5422/dw_mmc_250a.
>>>>> MMC card: absent, broken-cd quirk
>>>>> SD card: present
>>>>>
>>>> I doubt $SUBJECT patch in current form can resolve you issue. I have
>>>> already given comments on $subject patch.
>>>>
>>>> Can you try out below patch (I have not tested yet) on top of $SUBJECT patch?
>>>>
>>>> =======
>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>> index b0b57e3..ea87844 100644
>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>> @@ -101,6 +101,7 @@ struct idmac_desc {
>>>>  #endif /* CONFIG_MMC_DW_IDMAC */
>>>>
>>>>  static int dw_mci_card_busy(struct mmc_host *mmc);
>>>> +static void dw_mci_wait_busy(struct dw_mci_slot *slot);
>>>>  static bool dw_mci_reset(struct dw_mci *host);
>>>>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>>>
>>>> @@ -874,16 +875,22 @@ static void 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);
>>>>         unsigned int cmd_status = 0;
>>>> +       int re_try = 3; /* just random for now, 1 re-try should be ok */
>>>>
>>>> -       mci_writel(host, CMDARG, arg);
>>>> -       wmb();
>>>> -       mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>>>> +       while(re_try--) {
>>>> +               mci_writel(host, CMDARG, arg);
>>>> +               wmb();
>>>> +               mci_writel(host, CMD, SDMMC_CMD_START | cmd);
>>>>
>>>> -       while (time_before(jiffies, timeout)) {
>>>> -               cmd_status = mci_readl(host, CMD);
>>>> -               if (!(cmd_status & SDMMC_CMD_START))
>>>> -                       return;
>>>> +               while (time_before(jiffies, timeout)) {
>>>> +                       cmd_status = mci_readl(host, CMD);
>>>> +                       if (!(cmd_status & SDMMC_CMD_START))
>>>> +                               return;
>>>> +               }
>>>> +
>>>> +               dw_mci_wait_busy(slot);
>>>>         }
>>>> +
>>>>         dev_err(&slot->mmc->class_dev,
>>>>                 "Timeout sending command (cmd %#x arg %#x status %#x)\n",
>>>>                 cmd, arg, cmd_status);
>>>> @@ -925,8 +932,6 @@ static void dw_mci_setup_bus(struct dw_mci_slot
>>>> *slot, bool force_clkinit)
>>>>         /* We must continue to set bit 28 in CMD until the change is complete */
>>>>         if (host->state == STATE_WAITING_CMD11_DONE)
>>>>                 sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
>>>> -       else
>>>> -               dw_mci_wait_busy(slot);
>>>>
>>>>         if (!clock) {
>>>>                 mci_writel(host, CLKENA, 0);
>>>>
>>>> ===== end ======
>>> The reason why we are fail to send command is that we got data busy in
>>> none-switch-volt state(host->state != STATE_WAITING_CMD11_DONE).
>>> So:
>>> if(host->state != STATE_WAITING_CMD11_DONE), we must wait until data not busy,
>>> And if (host->state == STATE_WAITING_CMD11_DONE) we should not wait.
>>>
>>>>> System hangs during boot after few minutes kernel spits:
>>>>> [  242.188098] INFO: task kworker/u16:1:50 blocked for more than 120
>>>>> seconds.
>>>>> [  242.193524]       Not tainted
>>>>> 3.19.0-next-20150210-00002-gf96831b-dirty #3834
>>>>> [  242.200622] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
>>>>> disables this message.
>>>>> [  242.208422] kworker/u16:1   D c04766ac     0    50      2 0x00000000
>>>>> [  242.214756] Workqueue: kmmcd mmc_rescan
>>>>> [  242.218553] [<c04766ac>] (__schedule) from [<c0476a58>]
>>>>> (schedule+0x34/0x98)
>>>>> [  242.225591] [<c0476a58>] (schedule) from [<c047a4dc>]
>>>>> (schedule_timeout+0x110/0x164)
>>>>> [  242.233302] [<c047a4dc>] (schedule_timeout) from [<c04774f0>]
>>>>> (wait_for_common+0xb8/0x14c)
>>>>> [  242.241539] [<c04774f0>] (wait_for_common) from [<c0362138>]
>>>>> (mmc_wait_for_req+0x68/0x17c)
>>>>> [  242.249861] [<c0362138>] (mmc_wait_for_req) from [<c03622cc>]
>>>>> (mmc_wait_for_cmd+0x80/0xa0)
>>>>> [  242.258002] [<c03622cc>] (mmc_wait_for_cmd) from [<c0367e50>]
>>>>> (mmc_go_idle+0x78/0xf8)
>>>>> [  242.265796] [<c0367e50>] (mmc_go_idle) from [<c0363e2c>]
>>>>> (mmc_rescan+0x280/0x314)
>>>>> [  242.273253] [<c0363e2c>] (mmc_rescan) from [<c0034764>]
>>>>> (process_one_work+0x120/0x324)
>>>>> [  242.281135] [<c0034764>] (process_one_work) from [<c00349cc>]
>>>>> (worker_thread+0x30/0x42c)
>>>>> [  242.289194] [<c00349cc>] (worker_thread) from [<c003926c>]
>>>>> (kthread+0xd8/0xf4)
>>>>> [  242.296389] [<c003926c>] (kthread) from [<c000e7c0>]
>>>>> (ret_from_fork+0x14/0x34)
>>>>>
>>>>> Just for record, Exynos4412/dw_mmc_240a with the same configuration
>>>>> (no MMC card, broken-cd) works OK without patches.
>>> This is because mmc start command,but mmc_request_done() is't called.
>>> I have ever found this issue.
>>> I found that host does't get DTO interrupt when mmc send command to read data.
>>> I have sent a patch for it, see:
>>> https://patchwork.kernel.org/patch/5426531/
>>>
>>> Would you please merge it and test again?
>>
>> I have merged it and added quirk to exynos, but it does not help. There
>> is still timeout:
>>
> I don't think this DTO issue. I think we need a way to reproduce this,
> at least on Exyons5422/5800.
> what type of sd card is being used? Are you trying UHS-I mode by any chance?
> 
Emmc, sd card and sdio, all have this issue on rk3288,
I have NOT found data busy before send command, but still not get DTO interrupt.

And we have ever found little probability of no command done interrupt.

>> [  242.188178] INFO: task kworker/u16:1:50 blocked for more than 120
>> seconds.
>> [  242.193605]       Not tainted
>> 3.19.0-next-20150212-00003-g7850750-dirty #3841
>> [  242.200703] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
>> disables this message.
>> [  242.208592] kworker/u16:1   D c04755f4     0    50      2 0x00000000
>> [  242.214840] Workqueue: kmmcd mmc_rescan
>> [  242.218635] [<c04755f4>] (__schedule) from [<c04759a0>]
>> (schedule+0x34/0x98)
>> [  242.225671] [<c04759a0>] (schedule) from [<c0479424>]
>> (schedule_timeout+0x110/0x164)
>> [  242.233383] [<c0479424>] (schedule_timeout) from [<c0476438>]
>> (wait_for_common+0xb8/0x14c)
>> [  242.241619] [<c0476438>] (wait_for_common) from [<c0361600>]
>> (mmc_wait_for_req+0xb0/0x13c)
>> [  242.249848] [<c0361600>] (mmc_wait_for_req) from [<c036170c>]
>> (mmc_wait_for_cmd+0x80/0xa0)
>> [  242.258086] [<c036170c>] (mmc_wait_for_cmd) from [<c03676e0>]
>> (mmc_go_idle+0x78/0xf8)
>> [  242.265876] [<c03676e0>] (mmc_go_idle) from [<c0363700>]
>> (mmc_rescan+0x25c/0x2e4)
>> [  242.273333] [<c0363700>] (mmc_rescan) from [<c0034764>]
>> (process_one_work+0x120/0x324)
>> [  242.281216] [<c0034764>] (process_one_work) from [<c00349cc>]
>> (worker_thread+0x30/0x42c)
>> [  242.289275] [<c00349cc>] (worker_thread) from [<c003926c>]
>> (kthread+0xd8/0xf4)
>> [  242.296469] [<c003926c>] (kthread) from [<c000e7c0>]
>> (ret_from_fork+0x14/0x34)
>>
>>
>> Regards
>> Andrzej
>>
>>>>>
>>>>> Regards
>>>>> Andrzej
>>>>>
>>>>>>>>          if (!clock) {
>>>>>>>>                  mci_writel(host, CLKENA, 0);
>>>>>>>> --
>>>>>>>> 1.8.3.2
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> linux-arm-kernel mailing list
>>>>>>>> linux-arm-kernel@lists.infradead.org
>>>>>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>>>>>>
>>>>>>
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
>>>>>> the body of a message to majordomo@vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>>
>>>>
>>>>
>>>
>>
> 
> 
> 

^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v3 0/3] about data busy
  2015-02-09  7:25 ` [PATCH v2 0/2] about data busy Addy Ke
  2015-02-09  7:25   ` [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
  2015-02-09  7:25   ` [PATCH v2 2/2] mmc: dw_mmc: Don't start command while data busy Addy Ke
@ 2015-02-13 11:52   ` Addy Ke
  2015-02-13 11:52     ` [PATCH v3 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
                       ` (3 more replies)
  2 siblings, 4 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-13 11:52 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders
  Cc: heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, Addy Ke

patch 1: This patch can fix bug that controller is still data busy after
	 reset all blocks. After this patch, I still get data busy in
	 set_ios().

patch 2: This patch fix bug 'Timeout sending command'. After patch1 and
	 patch2, there is no mmc errors after:
	 cd /sys/bus/platform/drivers/dwmmc_rockchip
	 for i in $(seq 1 10000); do
  		echo "========================" $i
  		echo ff0c0000.dwmmc > unbind
  		sleep .5
  		echo ff0c0000.dwmmc > bind
  		sleep 2
	done
 
patch3: This patch fix bug that there is data busy before sdio send CMD53.
        But This patch is necessary for sd and mmc too.

Addy Ke (3):
  mmc: dw_mmc: update clock after host reach a stable voltage
  mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  mmc: dw_mmc: Don't start command while data busy

 drivers/mmc/host/dw_mmc.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v3 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-13 11:52   ` [PATCH v3 0/3] about " Addy Ke
@ 2015-02-13 11:52     ` Addy Ke
  2015-02-13 11:52     ` [PATCH v3 2/3] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-13 11:52 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders
  Cc: heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, Addy Ke

As show in mmc_power_up(), in MMC_POWER_UP state, the voltage isn't
stable and we may get 'data busy' which can't be cleaned by resetting
all blocks. So we should not send command to update clock in this state.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
 drivers/mmc/host/dw_mmc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 4d2e3c2..3472f9b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1102,7 +1102,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		drv_data->set_ios(slot->host, ios);
 
 	/* Slot specific timing and width adjustment */
-	dw_mci_setup_bus(slot, false);
+	if (ios->power_mode != MMC_POWER_UP)
+		dw_mci_setup_bus(slot, false);
 
 	if (slot->host->state == STATE_WAITING_CMD11_DONE && ios->clock != 0)
 		slot->host->state = STATE_IDLE;
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v3 2/3] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-13 11:52   ` [PATCH v3 0/3] about " Addy Ke
  2015-02-13 11:52     ` [PATCH v3 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
@ 2015-02-13 11:52     ` Addy Ke
  2015-02-13 11:52     ` [PATCH v3 3/3] mmc: dw_mmc: Don't start command while data busy Addy Ke
  2015-02-14  6:17     ` [PATCH v4 0/3] about " Addy Ke
  3 siblings, 0 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-13 11:52 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders
  Cc: heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, Addy Ke

Because of some uncertain factors, such as worse card or worse hardware,
DAT[3:0](the data lines) may be pulled down by card, and mmc controller
will be in busy state. This should not happend when mmc controller
send command to update card clocks. If this happends, mci_send_cmd will
be failed and we will get 'Timeout sending command', and then system will
be blocked. To avoid this, we need reset mmc controller.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
 drivers/mmc/host/dw_mmc.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3472f9b..f0d9da5 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -100,6 +100,7 @@ struct idmac_desc {
 };
 #endif /* CONFIG_MMC_DW_IDMAC */
 
+static int dw_mci_card_busy(struct mmc_host *mmc);
 static bool dw_mci_reset(struct dw_mci *host);
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
 
@@ -888,6 +889,35 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 		cmd, arg, cmd_status);
 }
 
+static void dw_mci_wait_busy(struct dw_mci_slot *slot)
+{
+	int ret;
+	struct dw_mci *host = slot->host;
+	unsigned long timeout = jiffies + msecs_to_jiffies(500);
+
+	if (host->state == STATE_WAITING_CMD11_DONE)
+		return;
+
+	do {
+		if (!dw_mci_card_busy(slot->mmc))
+			return;
+		usleep_range(50, 100);
+	} while (time_before(jiffies, timeout));
+
+	dev_err(host->dev, "Data busy (status %#x)\n",
+		mci_readl(slot->host, STATUS));
+
+	/*
+	 * Data busy, this should not happend when mmc controller send command
+	 * to update card clocks in non-volt-switch state. If it happends, we
+	 * should reset controller to avoid getting "Timeout sending command".
+	 */
+	ret = dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
+
+	/* Fail to reset controller or still data busy, WARN_ON! */
+	WARN_ON(!ret || dw_mci_card_busy(slot->mmc));
+}
+
 static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 {
 	struct dw_mci *host = slot->host;
@@ -896,6 +926,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 	u32 clk_en_a;
 	u32 sdmmc_cmd_bits = SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT;
 
+	dw_mci_wait_busy(slot);
+
 	/* We must continue to set bit 28 in CMD until the change is complete */
 	if (host->state == STATE_WAITING_CMD11_DONE)
 		sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v3 3/3] mmc: dw_mmc: Don't start command while data busy
  2015-02-13 11:52   ` [PATCH v3 0/3] about " Addy Ke
  2015-02-13 11:52     ` [PATCH v3 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
  2015-02-13 11:52     ` [PATCH v3 2/3] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
@ 2015-02-13 11:52     ` Addy Ke
  2015-02-14  6:17     ` [PATCH v4 0/3] about " Addy Ke
  3 siblings, 0 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-13 11:52 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders
  Cc: heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, Addy Ke

We should wait for data busy here in non-volt-switch state.
This may happend when sdio sends CMD53.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
 drivers/mmc/host/dw_mmc.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index f0d9da5..23507c9 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1076,6 +1076,12 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	WARN_ON(slot->mrq);
 
 	/*
+	 * We should wait for data busy here in non-volt-switch state.
+	 * This may happend when sdio sends CMD53.
+	 */
+	dw_mci_wait_busy(slot);
+
+	/*
 	 * The check for card presence and queueing of the request must be
 	 * atomic, otherwise the card could be removed in between and the
 	 * request wouldn't fail until another card was inserted.
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v4 0/3] about data busy
  2015-02-13 11:52   ` [PATCH v3 0/3] about " Addy Ke
                       ` (2 preceding siblings ...)
  2015-02-13 11:52     ` [PATCH v3 3/3] mmc: dw_mmc: Don't start command while data busy Addy Ke
@ 2015-02-14  6:17     ` Addy Ke
  2015-02-14  6:17       ` [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
                         ` (4 more replies)
  3 siblings, 5 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-14  6:17 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders
  Cc: heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, Addy Ke

patch 1: This patch can fix bug that controller is still data busy after
	 reset all blocks. After this patch, I still get data busy in
	 set_ios().

patch 2: This patch fix bug 'Timeout sending command'. After patch1 and
	 patch2, there is no mmc errors after:
	 cd /sys/bus/platform/drivers/dwmmc_rockchip
	 for i in $(seq 1 10000); do
  		echo "========================" $i
  		echo ff0c0000.dwmmc > unbind
  		sleep .5
  		echo ff0c0000.dwmmc > bind
  		sleep 2
	done
 
patch3: This patch fix bug that there is data busy before sdio send CMD53.
        But This patch is necessary for sd and mmc too.

Addy Ke (3):
  mmc: dw_mmc: update clock after host reach a stable voltage
  mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  mmc: dw_mmc: Don't start command while data busy

 drivers/mmc/host/dw_mmc.c | 41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-14  6:17     ` [PATCH v4 0/3] about " Addy Ke
@ 2015-02-14  6:17       ` Addy Ke
  2015-02-15 23:28         ` Alim Akhtar
  2015-02-14  6:17       ` [PATCH v4 2/3] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
                         ` (3 subsequent siblings)
  4 siblings, 1 reply; 43+ messages in thread
From: Addy Ke @ 2015-02-14  6:17 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders
  Cc: heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, Addy Ke

As show in mmc_power_up(), in MMC_POWER_UP state, the voltage isn't
stable and we may get 'data busy' which can't be cleaned by resetting
all blocks. So we should not send command to update clock in this state.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
 drivers/mmc/host/dw_mmc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 4d2e3c2..3472f9b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1102,7 +1102,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		drv_data->set_ios(slot->host, ios);
 
 	/* Slot specific timing and width adjustment */
-	dw_mci_setup_bus(slot, false);
+	if (ios->power_mode != MMC_POWER_UP)
+		dw_mci_setup_bus(slot, false);
 
 	if (slot->host->state == STATE_WAITING_CMD11_DONE && ios->clock != 0)
 		slot->host->state = STATE_IDLE;
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v4 2/3] mmc: dw_mmc: fix bug that cause 'Timeout sending command'
  2015-02-14  6:17     ` [PATCH v4 0/3] about " Addy Ke
  2015-02-14  6:17       ` [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
@ 2015-02-14  6:17       ` Addy Ke
  2015-02-14  6:17       ` [PATCH v4 3/3] mmc: dw_mmc: Don't start command while data busy Addy Ke
                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 43+ messages in thread
From: Addy Ke @ 2015-02-14  6:17 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders
  Cc: heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, Addy Ke

Because of some uncertain factors, such as worse card or worse hardware,
DAT[3:0](the data lines) may be pulled down by card, and mmc controller
will be in busy state. This should not happend when mmc controller
send command to update card clocks. If this happends, mci_send_cmd will
be failed and we will get 'Timeout sending command', and then system will
be blocked. To avoid this, we need reset mmc controller.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
Changes in v4:
- Retry to wait and reset all blocks until data unbusy.
  I have a sd card, which need retry 2 times to change to unbusy state.

---
 drivers/mmc/host/dw_mmc.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3472f9b..ac21863 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -100,6 +100,7 @@ struct idmac_desc {
 };
 #endif /* CONFIG_MMC_DW_IDMAC */
 
+static int dw_mci_card_busy(struct mmc_host *mmc);
 static bool dw_mci_reset(struct dw_mci *host);
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
 
@@ -888,6 +889,36 @@ static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg)
 		cmd, arg, cmd_status);
 }
 
+static void dw_mci_wait_busy(struct dw_mci_slot *slot)
+{
+	bool ret = true;
+	struct dw_mci *host = slot->host;
+	unsigned long timeout = jiffies + msecs_to_jiffies(500);
+
+	if (host->state == STATE_WAITING_CMD11_DONE)
+		return;
+
+	do {
+		do {
+			if (!dw_mci_card_busy(slot->mmc))
+				return;
+			usleep_range(50, 100);
+		} while (time_before(jiffies, timeout));
+
+		dev_err(host->dev, "Data busy (status %#x)\n",
+			mci_readl(slot->host, STATUS));
+
+		/*
+		 * Data busy, this should not happend when mmc controller
+		 * send command to update card clocks in non-volt-switch state.
+		 * If it happends, we should reset controller to avoid getting
+		 * "Timeout sending command".
+		 */
+		ret = dw_mci_ctrl_reset(host, SDMMC_CTRL_ALL_RESET_FLAGS);
+
+	} while (!ret || dw_mci_card_busy(slot->mmc));
+}
+
 static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 {
 	struct dw_mci *host = slot->host;
@@ -896,6 +927,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit)
 	u32 clk_en_a;
 	u32 sdmmc_cmd_bits = SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT;
 
+	dw_mci_wait_busy(slot);
+
 	/* We must continue to set bit 28 in CMD until the change is complete */
 	if (host->state == STATE_WAITING_CMD11_DONE)
 		sdmmc_cmd_bits |= SDMMC_CMD_VOLT_SWITCH;
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v4 3/3] mmc: dw_mmc: Don't start command while data busy
  2015-02-14  6:17     ` [PATCH v4 0/3] about " Addy Ke
  2015-02-14  6:17       ` [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
  2015-02-14  6:17       ` [PATCH v4 2/3] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
@ 2015-02-14  6:17       ` Addy Ke
  2015-02-20  0:21         ` Doug Anderson
  2015-02-15 11:41       ` [PATCH v4 0/3] about " Javier Martinez Canillas
  2015-02-20 19:03       ` Doug Anderson
  4 siblings, 1 reply; 43+ messages in thread
From: Addy Ke @ 2015-02-14  6:17 UTC (permalink / raw)
  To: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders
  Cc: heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip, Addy Ke

We should wait until unbusy before the next request.
But this does't need if the command is CMD13, which can access
SD Status register regardless of data busy.

Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
---
Changes in v4:
- CMD13 doesn't need wait until unbusy.

 drivers/mmc/host/dw_mmc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index ac21863..692d97a 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1076,6 +1076,10 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
 	WARN_ON(slot->mrq);
 
+	/* Wait until unbusy if the command isn't CMD13 */
+	if (mrq->cmd->opcode != MMC_SEND_STATUS)
+		dw_mci_wait_busy(slot);
+
 	/*
 	 * The check for card presence and queueing of the request must be
 	 * atomic, otherwise the card could be removed in between and the
-- 
1.8.3.2



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 0/3] about data busy
  2015-02-14  6:17     ` [PATCH v4 0/3] about " Addy Ke
                         ` (2 preceding siblings ...)
  2015-02-14  6:17       ` [PATCH v4 3/3] mmc: dw_mmc: Don't start command while data busy Addy Ke
@ 2015-02-15 11:41       ` Javier Martinez Canillas
  2015-02-16  5:48         ` Jaehoon Chung
  2015-02-19 10:55         ` addy ke
  2015-02-20 19:03       ` Doug Anderson
  4 siblings, 2 replies; 43+ messages in thread
From: Javier Martinez Canillas @ 2015-02-15 11:41 UTC (permalink / raw)
  To: Addy Ke
  Cc: Jaehoon Chung, Ulf Hansson, Olof Johansson, Alim Akhtar,
	Andrzej Hajda, Douglas Anderson, Heiko Stübner, cf, lintao,
	huangtao, Linux Kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip

Hello Addy,

On Sat, Feb 14, 2015 at 7:17 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
> patch 1: This patch can fix bug that controller is still data busy after
>          reset all blocks. After this patch, I still get data busy in
>          set_ios().
>
> patch 2: This patch fix bug 'Timeout sending command'. After patch1 and
>          patch2, there is no mmc errors after:
>          cd /sys/bus/platform/drivers/dwmmc_rockchip
>          for i in $(seq 1 10000); do
>                 echo "========================" $i
>                 echo ff0c0000.dwmmc > unbind
>                 sleep .5
>                 echo ff0c0000.dwmmc > bind
>                 sleep 2
>         done
>
> patch3: This patch fix bug that there is data busy before sdio send CMD53.
>         But This patch is necessary for sd and mmc too.
>

I faced the same 'Timeout sending command' error when trying to enable
support for the SDIO wifi chip attached to mmc@12210000 (mmc1) on an
Exynos5420 Peach Pit Chromebook. On booting the kernel log shows:

mmc_host mmc1: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000)

0x202000 == SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT so your patch
#2 dw_mci_setup_bus() avoids the mmc comand to time out. However, it
has a side effect since with your series the uSD that in mmc@12220000
(mmc2) fails to be detected and the kernel log shows:

[    5.466432] Waiting for root device /dev/mmcblk1p4...
[  240.169436] INFO: task kworker/u16:1:50 blocked for more than 120 seconds.
[  240.174844]       Not tainted
3.19.0-next-20150211-00006-g045d4aba96ce-dirty #476
[  240.182302] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
disables this message.
[  240.190109] kworker/u16:1   D c04c2710     0    50      2 0x00000000
[  240.196446] Workqueue: kmmcd mmc_rescan
[  240.200249] [<c04c2710>] (__schedule) from [<c04c2ac0>] (schedule+0x34/0x98)
[  240.207290] [<c04c2ac0>] (schedule) from [<c04c6568>]
(schedule_timeout+0x120/0x16c)
[  240.215009] [<c04c6568>] (schedule_timeout) from [<c04c3584>]
(wait_for_common+0xb0/0x154)
[  240.223251] [<c04c3584>] (wait_for_common) from [<c038a5ac>]
(mmc_wait_for_req+0xa0/0x140)
[  240.231492] [<c038a5ac>] (mmc_wait_for_req) from [<c038a6d4>]
(mmc_wait_for_cmd+0x88/0xa8)
[  240.239735] [<c038a6d4>] (mmc_wait_for_cmd) from [<c03905b0>]
(mmc_go_idle+0x78/0xf8)
[  240.247540] [<c03905b0>] (mmc_go_idle) from [<c038c578>]
(mmc_rescan+0x254/0x300)
[  240.255003] [<c038c578>] (mmc_rescan) from [<c00346e8>]
(process_one_work+0x120/0x324)
[  240.262897] [<c00346e8>] (process_one_work) from [<c0034a58>]
(worker_thread+0x138/0x464)
[  240.271048] [<c0034a58>] (worker_thread) from [<c0039070>]
(kthread+0xd8/0xf4)
[  240.278254] [<c0039070>] (kthread) from [<c000e680>]
(ret_from_fork+0x14/0x34)


By enabling debug I see that the card is detected in dw_mci_get_cd() though.

Alim suggested [0] that dw_mci_wait_busy() should be called in
mci_send_cmd() instead dw_mci_setup_bus() because the controller hangs
when when sending update clock cmd in different cases.

I modified [1] your patch #2 to do what Alim suggested and only with
that patch on top of linux-next I have neither the the "Timeout
sending command" error nor the uSD not getting detected errors. Linux
mounts the rootfs from the uSD and the wifi SDIO device is enumerated
and listed in /sys/bus/sdio/devices/

Does that also solve your issue?

Best regards,
Javier

[0]: https://lkml.org/lkml/2015/2/10/353
[1]: http://paste.debian.net/plain/148794

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-14  6:17       ` [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
@ 2015-02-15 23:28         ` Alim Akhtar
  2015-02-19 10:30           ` addy ke
  2015-02-19 23:49           ` Doug Anderson
  0 siblings, 2 replies; 43+ messages in thread
From: Alim Akhtar @ 2015-02-15 23:28 UTC (permalink / raw)
  To: Addy Ke
  Cc: Jaehoon Chung, Ulf Hansson, Olof Johansson, Andrzej Hajda,
	Douglas Anderson, Heiko Stübner, Eddie Cai, lintao,
	Tao Huang, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip

Hi Addy,

On Sat, Feb 14, 2015 at 11:47 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
> As show in mmc_power_up(), in MMC_POWER_UP state, the voltage isn't
> stable and we may get 'data busy' which can't be cleaned by resetting
> all blocks. So we should not send command to update clock in this state.
>
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
>  drivers/mmc/host/dw_mmc.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 4d2e3c2..3472f9b 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1102,7 +1102,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>                 drv_data->set_ios(slot->host, ios);
>
>         /* Slot specific timing and width adjustment */
> -       dw_mci_setup_bus(slot, false);
> +       if (ios->power_mode != MMC_POWER_UP)
> +               dw_mci_setup_bus(slot, false);
>
This looks a HACK to me.
If stabilizing host voltage regulator is the problem, can you try out
below patch, and see if this resolve your issue?

===========
[PATCH] mmc: dw_mmc: Wait for host voltage regulator to be stable

Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
---
 drivers/mmc/host/dw_mmc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 4d2e3c2..dc10fbb 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1202,6 +1202,9 @@ static int dw_mci_switch_voltage(struct mmc_host
*mmc, struct mmc_ios *ios)
  }
  mci_writel(host, UHS_REG, uhs);

+ /* wait for 5ms so that host voltage regulator is stable */
+ usleep_range(5000, 5500);
+
  return 0;
 }

===============

>         if (slot->host->state == STATE_WAITING_CMD11_DONE && ios->clock != 0)
>                 slot->host->state = STATE_IDLE;
> --
> 1.8.3.2
>
>



-- 
Regards,
Alim

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 0/3] about data busy
  2015-02-15 11:41       ` [PATCH v4 0/3] about " Javier Martinez Canillas
@ 2015-02-16  5:48         ` Jaehoon Chung
  2015-02-16 11:09           ` Javier Martinez Canillas
  2015-02-19 10:55         ` addy ke
  1 sibling, 1 reply; 43+ messages in thread
From: Jaehoon Chung @ 2015-02-16  5:48 UTC (permalink / raw)
  To: Javier Martinez Canillas, Addy Ke
  Cc: Ulf Hansson, Olof Johansson, Alim Akhtar, Andrzej Hajda,
	Douglas Anderson, Heiko Stübner, cf, lintao, huangtao,
	Linux Kernel, linux-mmc, linux-arm-kernel, linux-rockchip

On 02/15/2015 08:41 PM, Javier Martinez Canillas wrote:
> Hello Addy,
> 
> On Sat, Feb 14, 2015 at 7:17 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> patch 1: This patch can fix bug that controller is still data busy after
>>          reset all blocks. After this patch, I still get data busy in
>>          set_ios().
>>
>> patch 2: This patch fix bug 'Timeout sending command'. After patch1 and
>>          patch2, there is no mmc errors after:
>>          cd /sys/bus/platform/drivers/dwmmc_rockchip
>>          for i in $(seq 1 10000); do
>>                 echo "========================" $i
>>                 echo ff0c0000.dwmmc > unbind
>>                 sleep .5
>>                 echo ff0c0000.dwmmc > bind
>>                 sleep 2
>>         done
>>
>> patch3: This patch fix bug that there is data busy before sdio send CMD53.
>>         But This patch is necessary for sd and mmc too.
>>
> 
> I faced the same 'Timeout sending command' error when trying to enable
> support for the SDIO wifi chip attached to mmc@12210000 (mmc1) on an
> Exynos5420 Peach Pit Chromebook. On booting the kernel log shows:
> 
> mmc_host mmc1: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000)
> 
> 0x202000 == SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT so your patch
> #2 dw_mci_setup_bus() avoids the mmc comand to time out. However, it
> has a side effect since with your series the uSD that in mmc@12220000
> (mmc2) fails to be detected and the kernel log shows:
> 
> [    5.466432] Waiting for root device /dev/mmcblk1p4...
> [  240.169436] INFO: task kworker/u16:1:50 blocked for more than 120 seconds.
> [  240.174844]       Not tainted
> 3.19.0-next-20150211-00006-g045d4aba96ce-dirty #476
> [  240.182302] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
> disables this message.
> [  240.190109] kworker/u16:1   D c04c2710     0    50      2 0x00000000
> [  240.196446] Workqueue: kmmcd mmc_rescan
> [  240.200249] [<c04c2710>] (__schedule) from [<c04c2ac0>] (schedule+0x34/0x98)
> [  240.207290] [<c04c2ac0>] (schedule) from [<c04c6568>]
> (schedule_timeout+0x120/0x16c)
> [  240.215009] [<c04c6568>] (schedule_timeout) from [<c04c3584>]
> (wait_for_common+0xb0/0x154)
> [  240.223251] [<c04c3584>] (wait_for_common) from [<c038a5ac>]
> (mmc_wait_for_req+0xa0/0x140)
> [  240.231492] [<c038a5ac>] (mmc_wait_for_req) from [<c038a6d4>]
> (mmc_wait_for_cmd+0x88/0xa8)
> [  240.239735] [<c038a6d4>] (mmc_wait_for_cmd) from [<c03905b0>]
> (mmc_go_idle+0x78/0xf8)
> [  240.247540] [<c03905b0>] (mmc_go_idle) from [<c038c578>]
> (mmc_rescan+0x254/0x300)
> [  240.255003] [<c038c578>] (mmc_rescan) from [<c00346e8>]
> (process_one_work+0x120/0x324)
> [  240.262897] [<c00346e8>] (process_one_work) from [<c0034a58>]
> (worker_thread+0x138/0x464)
> [  240.271048] [<c0034a58>] (worker_thread) from [<c0039070>]
> (kthread+0xd8/0xf4)
> [  240.278254] [<c0039070>] (kthread) from [<c000e680>]
> (ret_from_fork+0x14/0x34)
> 
> 
> By enabling debug I see that the card is detected in dw_mci_get_cd() though.
> 
> Alim suggested [0] that dw_mci_wait_busy() should be called in
> mci_send_cmd() instead dw_mci_setup_bus() because the controller hangs
> when when sending update clock cmd in different cases.
> 
> I modified [1] your patch #2 to do what Alim suggested and only with
> that patch on top of linux-next I have neither the the "Timeout
> sending command" error nor the uSD not getting detected errors. Linux
> mounts the rootfs from the uSD and the wifi SDIO device is enumerated
> and listed in /sys/bus/sdio/devices/

it needs to check when clock value only update.
As Javier and Alim are mentioned, if check whether card is busy or not in setup_bus(),
should be processed unnecessary checking.
(According to TRM, before disabling clock, check whether card is busy or not.)
if my thinking is right, chekcing is located more exactly before mci_writel(host, CLKENA, 0).

And i recommend if CLK_GATE is enabled, clkgate_delay sets to the bigger value than 3.
I'm not sure Javier's issue is same thing..I will check more this.

Best Regards,
Jaehoon Chung

> 
> Does that also solve your issue?
> 
> Best regards,
> Javier
> 
> [0]: https://lkml.org/lkml/2015/2/10/353
> [1]: http://paste.debian.net/plain/148794
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 0/3] about data busy
  2015-02-16  5:48         ` Jaehoon Chung
@ 2015-02-16 11:09           ` Javier Martinez Canillas
  0 siblings, 0 replies; 43+ messages in thread
From: Javier Martinez Canillas @ 2015-02-16 11:09 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: Addy Ke, Ulf Hansson, Olof Johansson, Alim Akhtar, Andrzej Hajda,
	Douglas Anderson, Heiko Stübner, cf, lintao, huangtao,
	Linux Kernel, linux-mmc, linux-arm-kernel, linux-rockchip

Hello Jaehoon,

On Mon, Feb 16, 2015 at 6:48 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> On 02/15/2015 08:41 PM, Javier Martinez Canillas wrote:
>> I modified [1] your patch #2 to do what Alim suggested and only with
>> that patch on top of linux-next I have neither the the "Timeout
>> sending command" error nor the uSD not getting detected errors. Linux
>> mounts the rootfs from the uSD and the wifi SDIO device is enumerated
>> and listed in /sys/bus/sdio/devices/
>
> it needs to check when clock value only update.
> As Javier and Alim are mentioned, if check whether card is busy or not in setup_bus(),
> should be processed unnecessary checking.
> (According to TRM, before disabling clock, check whether card is busy or not.)
> if my thinking is right, chekcing is located more exactly before mci_writel(host, CLKENA, 0).
>
> And i recommend if CLK_GATE is enabled, clkgate_delay sets to the bigger value than 3.
> I'm not sure Javier's issue is same thing..I will check more this.
>

Thanks for checking, do you have access to a Peach Pit or Pi
Chromebook to reproduce the issue I reported? Please let me know if
you need any help from me.

> Best Regards,
> Jaehoon Chung
>

Best regards,
Javier

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-15 23:28         ` Alim Akhtar
@ 2015-02-19 10:30           ` addy ke
  2015-02-19 23:49           ` Doug Anderson
  1 sibling, 0 replies; 43+ messages in thread
From: addy ke @ 2015-02-19 10:30 UTC (permalink / raw)
  To: alim.akhtar
  Cc: jh80.chung, ulf.hansson, olof, a.hajda, dianders, heiko, cf,
	lintao, huangtao, linux-kernel, linux-mmc, linux-arm-kernel,
	linux-rockchip

Hi, Alim

Sorry for late reply.

On 2015/2/16 07:28, Alim Akhtar wrote:
> Hi Addy,
> 
> On Sat, Feb 14, 2015 at 11:47 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> As show in mmc_power_up(), in MMC_POWER_UP state, the voltage isn't
>> stable and we may get 'data busy' which can't be cleaned by resetting
>> all blocks. So we should not send command to update clock in this state.
>>
>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>> ---
>>  drivers/mmc/host/dw_mmc.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 4d2e3c2..3472f9b 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -1102,7 +1102,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>                 drv_data->set_ios(slot->host, ios);
>>
>>         /* Slot specific timing and width adjustment */
>> -       dw_mci_setup_bus(slot, false);
>> +       if (ios->power_mode != MMC_POWER_UP)
>> +               dw_mci_setup_bus(slot, false);
>>
> This looks a HACK to me.
> If stabilizing host voltage regulator is the problem, can you try out
> below patch, and see if this resolve your issue?

I have test by:
cd /sys/bus/platform/drivers/dwmmc_rockchip
for i in $(seq 1 10000); do
  echo "========================" $i
  echo ff0c0000.dwmmc > unbind
  sleep .5
  echo ff0c0000.dwmmc > bind
  sleep 2
done

There is no error.
I think this patch can resolve my issue, thank you.

Do you send this patch upstream, or can I put it in my patch list?

> 
> ===========
> [PATCH] mmc: dw_mmc: Wait for host voltage regulator to be stable
> 
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> ---
>  drivers/mmc/host/dw_mmc.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 4d2e3c2..dc10fbb 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1202,6 +1202,9 @@ static int dw_mci_switch_voltage(struct mmc_host
> *mmc, struct mmc_ios *ios)
>   }
>   mci_writel(host, UHS_REG, uhs);
> 
> + /* wait for 5ms so that host voltage regulator is stable */
> + usleep_range(5000, 5500);
> +
>   return 0;
>  }
> 
> ===============
> 
>>         if (slot->host->state == STATE_WAITING_CMD11_DONE && ios->clock != 0)
>>                 slot->host->state = STATE_IDLE;
>> --
>> 1.8.3.2
>>
>>
> 
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 0/3] about data busy
  2015-02-15 11:41       ` [PATCH v4 0/3] about " Javier Martinez Canillas
  2015-02-16  5:48         ` Jaehoon Chung
@ 2015-02-19 10:55         ` addy ke
  1 sibling, 0 replies; 43+ messages in thread
From: addy ke @ 2015-02-19 10:55 UTC (permalink / raw)
  To: javier
  Cc: jh80.chung, ulf.hansson, olof, alim.akhtar, a.hajda, dianders,
	heiko, cf, lintao, huangtao, linux-kernel, linux-mmc,
	linux-arm-kernel, linux-rockchip

Hi, Javier and Alim

These days are Spring Festival holiday.
Sorry for late reply.

On 2015/2/15 19:41, Javier Martinez Canillas wrote:
> Hello Addy,
> 
> On Sat, Feb 14, 2015 at 7:17 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> patch 1: This patch can fix bug that controller is still data busy after
>>          reset all blocks. After this patch, I still get data busy in
>>          set_ios().
>>
>> patch 2: This patch fix bug 'Timeout sending command'. After patch1 and
>>          patch2, there is no mmc errors after:
>>          cd /sys/bus/platform/drivers/dwmmc_rockchip
>>          for i in $(seq 1 10000); do
>>                 echo "========================" $i
>>                 echo ff0c0000.dwmmc > unbind
>>                 sleep .5
>>                 echo ff0c0000.dwmmc > bind
>>                 sleep 2
>>         done
>>
>> patch3: This patch fix bug that there is data busy before sdio send CMD53.
>>         But This patch is necessary for sd and mmc too.
>>
> 
> I faced the same 'Timeout sending command' error when trying to enable
> support for the SDIO wifi chip attached to mmc@12210000 (mmc1) on an
> Exynos5420 Peach Pit Chromebook. On booting the kernel log shows:
> 
> mmc_host mmc1: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000)
> 
> 0x202000 == SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT so your patch
> #2 dw_mci_setup_bus() avoids the mmc comand to time out. However, it
> has a side effect since with your series the uSD that in mmc@12220000
> (mmc2) fails to be detected and the kernel log shows:
> 
> [    5.466432] Waiting for root device /dev/mmcblk1p4...
> [  240.169436] INFO: task kworker/u16:1:50 blocked for more than 120 seconds.
> [  240.174844]       Not tainted
> 3.19.0-next-20150211-00006-g045d4aba96ce-dirty #476
> [  240.182302] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs"
> disables this message.
> [  240.190109] kworker/u16:1   D c04c2710     0    50      2 0x00000000
> [  240.196446] Workqueue: kmmcd mmc_rescan
> [  240.200249] [<c04c2710>] (__schedule) from [<c04c2ac0>] (schedule+0x34/0x98)
> [  240.207290] [<c04c2ac0>] (schedule) from [<c04c6568>]
> (schedule_timeout+0x120/0x16c)
> [  240.215009] [<c04c6568>] (schedule_timeout) from [<c04c3584>]
> (wait_for_common+0xb0/0x154)
> [  240.223251] [<c04c3584>] (wait_for_common) from [<c038a5ac>]
> (mmc_wait_for_req+0xa0/0x140)
> [  240.231492] [<c038a5ac>] (mmc_wait_for_req) from [<c038a6d4>]
> (mmc_wait_for_cmd+0x88/0xa8)
> [  240.239735] [<c038a6d4>] (mmc_wait_for_cmd) from [<c03905b0>]
> (mmc_go_idle+0x78/0xf8)
> [  240.247540] [<c03905b0>] (mmc_go_idle) from [<c038c578>]
> (mmc_rescan+0x254/0x300)
> [  240.255003] [<c038c578>] (mmc_rescan) from [<c00346e8>]
> (process_one_work+0x120/0x324)
> [  240.262897] [<c00346e8>] (process_one_work) from [<c0034a58>]
> (worker_thread+0x138/0x464)
> [  240.271048] [<c0034a58>] (worker_thread) from [<c0039070>]
> (kthread+0xd8/0xf4)
> [  240.278254] [<c0039070>] (kthread) from [<c000e680>]
> (ret_from_fork+0x14/0x34)
> 
> 
> By enabling debug I see that the card is detected in dw_mci_get_cd() though.
> 
> Alim suggested [0] that dw_mci_wait_busy() should be called in
> mci_send_cmd() instead dw_mci_setup_bus() because the controller hangs
> when when sending update clock cmd in different cases.
> 
> I modified [1] your patch #2 to do what Alim suggested and only with
> that patch on top of linux-next I have neither the the "Timeout
> sending command" error nor the uSD not getting detected errors. Linux
> mounts the rootfs from the uSD and the wifi SDIO device is enumerated
> and listed in /sys/bus/sdio/devices/
> 
> Does that also solve your issue?

After merge Alim patch,and set re_try 8,
it can pass test by:
cd /sys/bus/platform/drivers/dwmmc_rockchip
for i in $(seq 1 10000); do
  echo "========================" $i
  echo ff0c0000.dwmmc > unbind
  sleep .5
  echo ff0c0000.dwmmc > bind
  sleep 2
done

My card is ADATA UHS-1 card(SDR50).
The maximum retry count is 6.

[ 1146.907596] mmc1: card 59b4 removed
[ 1147.421036] dwmmc_rockchip ff0c0000.dwmmc: Using internal DMA controller.
[ 1147.427827] dwmmc_rockchip ff0c0000.dwmmc: Version ID is 270a
[ 1147.433958] dwmmc_rockchip ff0c0000.dwmmc: DW MMC controller at irq 64, 32 bit host data width, 256 deep fifo
[ 1147.444269] dwmmc_rockchip ff0c0000.dwmmc: Got CD GPIO #221.
[ 1147.450381] dwmmc_rockchip ff0c0000.dwmmc: Got WP GPIO #226.
[ 1147.456046] ff0c0000.dwmmc supply card-external-vcc not found, using dummy regulator
[ 1148.519400] dwmmc_rockchip ff0c0000.dwmmc: Data busy (status 0x206)
[ 1149.019451] dwmmc_rockchip ff0c0000.dwmmc: Data busy (status 0x206)
[ 1149.519382] dwmmc_rockchip ff0c0000.dwmmc: Data busy (status 0x206)
[ 1150.019492] dwmmc_rockchip ff0c0000.dwmmc: Data busy (status 0x206)
[ 1150.519442] dwmmc_rockchip ff0c0000.dwmmc: Data busy (status 0x206)
>>>>>>>>>>>>>>>>>>>>>>>>> if re_try is 5, I still get "Timeout sending command".
[ 1150.525711] mmc_host mmc1: Timeout sending command (cmd 0x202000 arg 0x0 status 0x80202000)
[ 1150.534723] rockchip-iodomain io-domains.25: Setting to 3300000 done

So re_try must bigger than 6, but I don't known which value is reansonable.
Do you have any idear about it?

This is the patch Alim suggests:
+       int re_try = 8; /* just random for now, 1 re-try should be ok */

-       mci_writel(host, CMDARG, arg);
-       wmb();
-       mci_writel(host, CMD, SDMMC_CMD_START | cmd);
+       while(re_try--) {
+               mci_writel(host, CMDARG, arg);
+               wmb();
+               mci_writel(host, CMD, SDMMC_CMD_START | cmd);

-       while (time_before(jiffies, timeout)) {
-               cmd_status = mci_readl(host, CMD);
-               if (!(cmd_status & SDMMC_CMD_START))
-                       return;
+               while (time_before(jiffies, timeout)) {
+                       cmd_status = mci_readl(host, CMD);
+                       if (!(cmd_status & SDMMC_CMD_START))
+                               return;
+               }
+
+               dw_mci_wait_busy(slot);
> 
> Best regards,
> Javier
> 
> [0]: https://lkml.org/lkml/2015/2/10/353
> [1]: http://paste.debian.net/plain/148794
> 
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-15 23:28         ` Alim Akhtar
  2015-02-19 10:30           ` addy ke
@ 2015-02-19 23:49           ` Doug Anderson
  2015-02-20  0:02             ` Russell King - ARM Linux
                               ` (2 more replies)
  1 sibling, 3 replies; 43+ messages in thread
From: Doug Anderson @ 2015-02-19 23:49 UTC (permalink / raw)
  To: Alim Akhtar, Addy Ke
  Cc: Jaehoon Chung, Ulf Hansson, Olof Johansson, Andrzej Hajda,
	Heiko Stübner, Eddie Cai, lintao, Tao Huang, linux-kernel,
	linux-mmc, linux-arm-kernel, open list:ARM/Rockchip SoC...,
	Javier Martinez Canillas

Alim and Addy,

On Sun, Feb 15, 2015 at 3:28 PM, Alim Akhtar <alim.akhtar@gmail.com> wrote:
> Hi Addy,
>
> On Sat, Feb 14, 2015 at 11:47 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
>> As show in mmc_power_up(), in MMC_POWER_UP state, the voltage isn't
>> stable and we may get 'data busy' which can't be cleaned by resetting
>> all blocks. So we should not send command to update clock in this state.
>>
>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>> ---
>>  drivers/mmc/host/dw_mmc.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 4d2e3c2..3472f9b 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -1102,7 +1102,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>                 drv_data->set_ios(slot->host, ios);
>>
>>         /* Slot specific timing and width adjustment */
>> -       dw_mci_setup_bus(slot, false);
>> +       if (ios->power_mode != MMC_POWER_UP)
>> +               dw_mci_setup_bus(slot, false);
>>
> This looks a HACK to me.
> If stabilizing host voltage regulator is the problem, can you try out
> below patch, and see if this resolve your issue?

Actually, IMHO Alim's patch is more of a hack than Addy's.  There's
already a 10ms delay between "power up" and "power on" in the MMC core
in mmc_power_up() state.  That delay is commented as:

  /*
   * This delay should be sufficient to allow the power supply
   * to reach the minimum voltage.
   */
  mmc_delay(10);

That means that assuming that the voltage is stable in MMC_POWER_UP is
not valid anyway.


Addy's patch certainly needs more comments.  In another context Olof suggested:

/*
 * Skip bus setup while voltage is still stabilizing. Instead,
 * bus setup will be done at MMC_POWER_ON.
 */


...thinking about this more, though: really the voltage should be
stabilized when the regulator call returns (see my comments below).
In actuality the "right" fix might be to just rearrange this function
a little not to turn the clock on _before_ we even try to turn the
voltage on.

I've got that coded up but I'm still testing it...  If you want to try
it too, you can find it at
<https://chromium-review.googlesource.com/251341>.

Note that without my patch I find that I _really_ need Addy's patch to
make sure that the card isn't busy in setup_bus.  With my patch Addy's
code catches the card busy less often.  I'm still trying to see if
there's a way to totally remove the need for his setup_bus and still
trying to grok all the patches flying around...


> ===========
> [PATCH] mmc: dw_mmc: Wait for host voltage regulator to be stable
>
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> ---
>  drivers/mmc/host/dw_mmc.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 4d2e3c2..dc10fbb 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1202,6 +1202,9 @@ static int dw_mci_switch_voltage(struct mmc_host
> *mmc, struct mmc_ios *ios)
>   }
>   mci_writel(host, UHS_REG, uhs);
>
> + /* wait for 5ms so that host voltage regulator is stable */
> + usleep_range(5000, 5500);
> +

Alim: if you have some other instance where you actually need VQMMC to
stabilize it should probably be done in a different way.  If I
understand correctly it is the regulator core's job to make sure that
voltage is stable before returning.  If you have a gpio-regulator you
may be able to use "startup-delay-us" to specify how long the
regulator takes to come up.  You could also look at
'regulator-enable-ramp-delay'

-Doug

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-19 23:49           ` Doug Anderson
@ 2015-02-20  0:02             ` Russell King - ARM Linux
  2015-02-20  1:04             ` Doug Anderson
  2015-02-25  7:52             ` Alim Akhtar
  2 siblings, 0 replies; 43+ messages in thread
From: Russell King - ARM Linux @ 2015-02-20  0:02 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Alim Akhtar, Addy Ke, Tao Huang, lintao, Ulf Hansson,
	Heiko Stübner, Andrzej Hajda, linux-mmc, linux-kernel,
	Jaehoon Chung, Eddie Cai, Olof Johansson,
	open list:ARM/Rockchip SoC...,
	Javier Martinez Canillas, linux-arm-kernel

On Thu, Feb 19, 2015 at 03:49:46PM -0800, Doug Anderson wrote:
> Alim and Addy,
> 
> On Sun, Feb 15, 2015 at 3:28 PM, Alim Akhtar <alim.akhtar@gmail.com> wrote:
> > Hi Addy,
> >
> > On Sat, Feb 14, 2015 at 11:47 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
> >> As show in mmc_power_up(), in MMC_POWER_UP state, the voltage isn't
> >> stable and we may get 'data busy' which can't be cleaned by resetting
> >> all blocks. So we should not send command to update clock in this state.
> >>
> >> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> >> ---
> >>  drivers/mmc/host/dw_mmc.c | 3 ++-
> >>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> >> index 4d2e3c2..3472f9b 100644
> >> --- a/drivers/mmc/host/dw_mmc.c
> >> +++ b/drivers/mmc/host/dw_mmc.c
> >> @@ -1102,7 +1102,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> >>                 drv_data->set_ios(slot->host, ios);
> >>
> >>         /* Slot specific timing and width adjustment */
> >> -       dw_mci_setup_bus(slot, false);
> >> +       if (ios->power_mode != MMC_POWER_UP)
> >> +               dw_mci_setup_bus(slot, false);
> >>
> > This looks a HACK to me.
> > If stabilizing host voltage regulator is the problem, can you try out
> > below patch, and see if this resolve your issue?
> 
> Actually, IMHO Alim's patch is more of a hack than Addy's.  There's
> already a 10ms delay between "power up" and "power on" in the MMC core
> in mmc_power_up() state.  That delay is commented as:
> 
>   /*
>    * This delay should be sufficient to allow the power supply
>    * to reach the minimum voltage.
>    */
>   mmc_delay(10);
> 
> That means that assuming that the voltage is stable in MMC_POWER_UP is
> not valid anyway.
> 
> 
> Addy's patch certainly needs more comments.  In another context Olof suggested:
> 
> /*
>  * Skip bus setup while voltage is still stabilizing. Instead,
>  * bus setup will be done at MMC_POWER_ON.
>  */
> 
> 
> ...thinking about this more, though: really the voltage should be
> stabilized when the regulator call returns (see my comments below).
> In actuality the "right" fix might be to just rearrange this function
> a little not to turn the clock on _before_ we even try to turn the
> voltage on.

This is exactly why I've been saying that we need to get away from the
POWER_UP vs POWER_ON stuff.  We instead need a _single_ call into
drivers to tell them to apply power and bring the card to a state
where it can be talked to.

That includes waiting for the power to stabilise, and sending the
initial clocks to allow the card to initialise.

In the case of extra GPIOs, host drivers will need to call back into
the MMC core at the point where they have stabilised the power.

The current situation where we split the power-up/power-on sequence
between the host drivers and the core is really a hinderance to getting
a working implementation - it's additional complexity where none is
needed.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 3/3] mmc: dw_mmc: Don't start command while data busy
  2015-02-14  6:17       ` [PATCH v4 3/3] mmc: dw_mmc: Don't start command while data busy Addy Ke
@ 2015-02-20  0:21         ` Doug Anderson
  0 siblings, 0 replies; 43+ messages in thread
From: Doug Anderson @ 2015-02-20  0:21 UTC (permalink / raw)
  To: Addy Ke
  Cc: Jaehoon Chung, Ulf Hansson, Olof Johansson, Alim Akhtar,
	Andrzej Hajda, Heiko Stübner, Eddie Cai, lintao, Tao Huang,
	linux-kernel, linux-mmc, linux-arm-kernel,
	open list:ARM/Rockchip SoC...,
	Javier Martinez Canillas

Addy,

On Fri, Feb 13, 2015 at 10:17 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
> We should wait until unbusy before the next request.
> But this does't need if the command is CMD13, which can access
> SD Status register regardless of data busy.
>
> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
> ---
> Changes in v4:
> - CMD13 doesn't need wait until unbusy.
>
>  drivers/mmc/host/dw_mmc.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index ac21863..692d97a 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1076,6 +1076,10 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>
>         WARN_ON(slot->mrq);
>
> +       /* Wait until unbusy if the command isn't CMD13 */
> +       if (mrq->cmd->opcode != MMC_SEND_STATUS)
> +               dw_mci_wait_busy(slot);
> +

I think you need to be more general.  You really should be checking
"cmd_flags & SDMMC_CMD_PRV_DAT_WAIT".  That leverages dw_mmc's
knowledge about whether it needs to wait.  Right now you'll be waiting
for CMD52 (SDIO) which I don't think is a good idea.

It also seems like this would be better in dw_mci_start_command() so
that we have the least chance of hitting the case.  The downside is
that you can't sleep there, though...  Hrm.

I updated a version of my take on this at
<https://chromium-review.googlesource.com/#/c/244850/>.  I'll put a
timeout on it soon-ish.  Any extra testing that folks can do would be
appreciated...

-Doug

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-19 23:49           ` Doug Anderson
  2015-02-20  0:02             ` Russell King - ARM Linux
@ 2015-02-20  1:04             ` Doug Anderson
  2015-02-20 19:05               ` Doug Anderson
  2015-02-25  7:52             ` Alim Akhtar
  2 siblings, 1 reply; 43+ messages in thread
From: Doug Anderson @ 2015-02-20  1:04 UTC (permalink / raw)
  To: Alim Akhtar, Addy Ke
  Cc: Jaehoon Chung, Ulf Hansson, Olof Johansson, Andrzej Hajda,
	Heiko Stübner, Eddie Cai, lintao, Tao Huang, linux-kernel,
	linux-mmc, linux-arm-kernel, open list:ARM/Rockchip SoC...,
	Javier Martinez Canillas

Hi,

On Thu, Feb 19, 2015 at 3:49 PM, Doug Anderson <dianders@chromium.org> wrote:
> I've got that coded up but I'm still testing it...  If you want to try
> it too, you can find it at
> <https://chromium-review.googlesource.com/251341>.
>
> Note that without my patch I find that I _really_ need Addy's patch to
> make sure that the card isn't busy in setup_bus.  With my patch Addy's
> code catches the card busy less often.  I'm still trying to see if
> there's a way to totally remove the need for his setup_bus and still
> trying to grok all the patches flying around...

Ah, this might be the magic needed:

https://chromium-review.googlesource.com/251344


I think that together with the previous patch things are happy for me
without any of Addy's patches, though it's the end of my work day and
I haven't given this nearly as much testing as I'd like.

I'll continue testing tomorrow and then post both patches together upstream.

-Doug

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 0/3] about data busy
  2015-02-14  6:17     ` [PATCH v4 0/3] about " Addy Ke
                         ` (3 preceding siblings ...)
  2015-02-15 11:41       ` [PATCH v4 0/3] about " Javier Martinez Canillas
@ 2015-02-20 19:03       ` Doug Anderson
  4 siblings, 0 replies; 43+ messages in thread
From: Doug Anderson @ 2015-02-20 19:03 UTC (permalink / raw)
  To: Addy Ke
  Cc: Jaehoon Chung, Ulf Hansson, Olof Johansson, Alim Akhtar,
	Andrzej Hajda, Heiko Stübner, Eddie Cai, lintao, Tao Huang,
	linux-kernel, linux-mmc, linux-arm-kernel,
	open list:ARM/Rockchip SoC...

Hi,

On Fri, Feb 13, 2015 at 10:17 PM, Addy Ke <addy.ke@rock-chips.com> wrote:
> patch 1: This patch can fix bug that controller is still data busy after
>          reset all blocks. After this patch, I still get data busy in
>          set_ios().
>
> patch 2: This patch fix bug 'Timeout sending command'. After patch1 and
>          patch2, there is no mmc errors after:
>          cd /sys/bus/platform/drivers/dwmmc_rockchip
>          for i in $(seq 1 10000); do
>                 echo "========================" $i
>                 echo ff0c0000.dwmmc > unbind
>                 sleep .5
>                 echo ff0c0000.dwmmc > bind
>                 sleep 2
>         done
>
> patch3: This patch fix bug that there is data busy before sdio send CMD53.
>         But This patch is necessary for sd and mmc too.
>
> Addy Ke (3):
>   mmc: dw_mmc: update clock after host reach a stable voltage
>   mmc: dw_mmc: fix bug that cause 'Timeout sending command'
>   mmc: dw_mmc: Don't start command while data busy
>
>  drivers/mmc/host/dw_mmc.c | 41 ++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 40 insertions(+), 1 deletion(-)

A little hard to follow all the patches flying around (so I'll
probably reply a few different places with the same info), but I
believe that all of Addy's patches (with the exception of the one
intended to fix mmc_test which needs to be spun by him for a bugfix)
can be replaced with:

* mmc: dw_mmc: Don't start commands while busy
  https://patchwork.kernel.org/patch/5858221/

* mmc: dw_mmc: Make sure we only adjust the clock when power is on
  https://patchwork.kernel.org/patch/5858261/

* mmc: dw_mmc: Give a good reset after we give power
  https://patchwork.kernel.org/patch/5858281/


In order to avoid further spreading info out among several patches,
I'd request that you don't respond here but instead respond to my
posted patches.  Thanks!

-Doug

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-20  1:04             ` Doug Anderson
@ 2015-02-20 19:05               ` Doug Anderson
  0 siblings, 0 replies; 43+ messages in thread
From: Doug Anderson @ 2015-02-20 19:05 UTC (permalink / raw)
  To: Alim Akhtar, Addy Ke
  Cc: Jaehoon Chung, Ulf Hansson, Olof Johansson, Andrzej Hajda,
	Heiko Stübner, Eddie Cai, lintao, Tao Huang, linux-kernel,
	linux-mmc, linux-arm-kernel, open list:ARM/Rockchip SoC...,
	Javier Martinez Canillas

Hi,

On Thu, Feb 19, 2015 at 5:04 PM, Doug Anderson <dianders@chromium.org> wrote:
> Hi,
>
> On Thu, Feb 19, 2015 at 3:49 PM, Doug Anderson <dianders@chromium.org> wrote:
>> I've got that coded up but I'm still testing it...  If you want to try
>> it too, you can find it at
>> <https://chromium-review.googlesource.com/251341>.
>>
>> Note that without my patch I find that I _really_ need Addy's patch to
>> make sure that the card isn't busy in setup_bus.  With my patch Addy's
>> code catches the card busy less often.  I'm still trying to see if
>> there's a way to totally remove the need for his setup_bus and still
>> trying to grok all the patches flying around...
>
> Ah, this might be the magic needed:
>
> https://chromium-review.googlesource.com/251344
>
>
> I think that together with the previous patch things are happy for me
> without any of Addy's patches, though it's the end of my work day and
> I haven't given this nearly as much testing as I'd like.
>
> I'll continue testing tomorrow and then post both patches together upstream.

OK, posted three patches upstream...

A little hard to follow all the patches flying around (so I'll
probably reply a few different places with the same info), but I
believe that all of Addy's patches (with the exception of the one
intended to fix mmc_test which needs to be spun by him for a bugfix)
can be replaced with:

* mmc: dw_mmc: Don't start commands while busy
  https://patchwork.kernel.org/patch/5858221/

* mmc: dw_mmc: Make sure we only adjust the clock when power is on
  https://patchwork.kernel.org/patch/5858261/

* mmc: dw_mmc: Give a good reset after we give power
  https://patchwork.kernel.org/patch/5858281/


In order to avoid further spreading info out among several patches,
I'd request that you don't respond here but instead respond to my
posted patches.  Thanks!

-Doug

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-19 23:49           ` Doug Anderson
  2015-02-20  0:02             ` Russell King - ARM Linux
  2015-02-20  1:04             ` Doug Anderson
@ 2015-02-25  7:52             ` Alim Akhtar
  2015-02-25  9:56               ` Jaehoon Chung
  2015-02-25 21:05               ` Doug Anderson
  2 siblings, 2 replies; 43+ messages in thread
From: Alim Akhtar @ 2015-02-25  7:52 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Addy Ke, Jaehoon Chung, Ulf Hansson, Olof Johansson,
	Andrzej Hajda, Heiko Stübner, Eddie Cai, lintao, Tao Huang,
	linux-kernel, linux-mmc, linux-arm-kernel,
	open list:ARM/Rockchip SoC...,
	Javier Martinez Canillas

Hi Doug,


On Fri, Feb 20, 2015 at 5:19 AM, Doug Anderson <dianders@chromium.org> wrote:
> Alim and Addy,
>
> On Sun, Feb 15, 2015 at 3:28 PM, Alim Akhtar <alim.akhtar@gmail.com> wrote:
>> Hi Addy,
>>
>> On Sat, Feb 14, 2015 at 11:47 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>> As show in mmc_power_up(), in MMC_POWER_UP state, the voltage isn't
>>> stable and we may get 'data busy' which can't be cleaned by resetting
>>> all blocks. So we should not send command to update clock in this state.
>>>
>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>> ---
>>>  drivers/mmc/host/dw_mmc.c | 3 ++-
>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index 4d2e3c2..3472f9b 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -1102,7 +1102,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>                 drv_data->set_ios(slot->host, ios);
>>>
>>>         /* Slot specific timing and width adjustment */
>>> -       dw_mci_setup_bus(slot, false);
>>> +       if (ios->power_mode != MMC_POWER_UP)
>>> +               dw_mci_setup_bus(slot, false);
>>>
>> This looks a HACK to me.
>> If stabilizing host voltage regulator is the problem, can you try out
>> below patch, and see if this resolve your issue?
>
> Actually, IMHO Alim's patch is more of a hack than Addy's.  There's
> already a 10ms delay between "power up" and "power on" in the MMC core
> in mmc_power_up() state.  That delay is commented as:
>
Well, my suggestion (adding 5ms in switch_volatge) was based on DW_MMC
databook (V2.41a) section "7.4.1.2 Voltage switch Normal Scenario"
step #7 which says:" After the 5ms timer expires, the host voltage
regulator is stable".

PS: I have limited to no access of my mails and workstation until
March 9th, so replies will be slow.

>   /*
>    * This delay should be sufficient to allow the power supply
>    * to reach the minimum voltage.
>    */
>   mmc_delay(10);
>
> That means that assuming that the voltage is stable in MMC_POWER_UP is
> not valid anyway.
>
>
> Addy's patch certainly needs more comments.  In another context Olof suggested:
>
> /*
>  * Skip bus setup while voltage is still stabilizing. Instead,
>  * bus setup will be done at MMC_POWER_ON.
>  */
>
>
> ...thinking about this more, though: really the voltage should be
> stabilized when the regulator call returns (see my comments below).
> In actuality the "right" fix might be to just rearrange this function
> a little not to turn the clock on _before_ we even try to turn the
> voltage on.
>
> I've got that coded up but I'm still testing it...  If you want to try
> it too, you can find it at
> <https://chromium-review.googlesource.com/251341>.
>
> Note that without my patch I find that I _really_ need Addy's patch to
> make sure that the card isn't busy in setup_bus.  With my patch Addy's
> code catches the card busy less often.  I'm still trying to see if
> there's a way to totally remove the need for his setup_bus and still
> trying to grok all the patches flying around...
>
>
>> ===========
>> [PATCH] mmc: dw_mmc: Wait for host voltage regulator to be stable
>>
>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>> ---
>>  drivers/mmc/host/dw_mmc.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 4d2e3c2..dc10fbb 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -1202,6 +1202,9 @@ static int dw_mci_switch_voltage(struct mmc_host
>> *mmc, struct mmc_ios *ios)
>>   }
>>   mci_writel(host, UHS_REG, uhs);
>>
>> + /* wait for 5ms so that host voltage regulator is stable */
>> + usleep_range(5000, 5500);
>> +
>
> Alim: if you have some other instance where you actually need VQMMC to
> stabilize it should probably be done in a different way.  If I
> understand correctly it is the regulator core's job to make sure that
> voltage is stable before returning.  If you have a gpio-regulator you
> may be able to use "startup-delay-us" to specify how long the
> regulator takes to come up.  You could also look at
> 'regulator-enable-ramp-delay'
>
> -Doug



-- 
Regards,
Alim

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-25  7:52             ` Alim Akhtar
@ 2015-02-25  9:56               ` Jaehoon Chung
  2015-02-25 21:05               ` Doug Anderson
  1 sibling, 0 replies; 43+ messages in thread
From: Jaehoon Chung @ 2015-02-25  9:56 UTC (permalink / raw)
  To: Alim Akhtar, Doug Anderson
  Cc: Addy Ke, Jaehoon Chung, Ulf Hansson, Olof Johansson,
	Andrzej Hajda, Heiko Stübner, Eddie Cai, lintao, Tao Huang,
	linux-kernel, linux-mmc, linux-arm-kernel,
	open list:ARM/Rockchip SoC...,
	Javier Martinez Canillas

Hi,

On 02/25/2015 04:52 PM, Alim Akhtar wrote:
> Hi Doug,
> 
> 
> On Fri, Feb 20, 2015 at 5:19 AM, Doug Anderson <dianders@chromium.org> wrote:
>> Alim and Addy,
>>
>> On Sun, Feb 15, 2015 at 3:28 PM, Alim Akhtar <alim.akhtar@gmail.com> wrote:
>>> Hi Addy,
>>>
>>> On Sat, Feb 14, 2015 at 11:47 AM, Addy Ke <addy.ke@rock-chips.com> wrote:
>>>> As show in mmc_power_up(), in MMC_POWER_UP state, the voltage isn't
>>>> stable and we may get 'data busy' which can't be cleaned by resetting
>>>> all blocks. So we should not send command to update clock in this state.
>>>>
>>>> Signed-off-by: Addy Ke <addy.ke@rock-chips.com>
>>>> ---
>>>>  drivers/mmc/host/dw_mmc.c | 3 ++-
>>>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>> index 4d2e3c2..3472f9b 100644
>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>> @@ -1102,7 +1102,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>                 drv_data->set_ios(slot->host, ios);
>>>>
>>>>         /* Slot specific timing and width adjustment */
>>>> -       dw_mci_setup_bus(slot, false);
>>>> +       if (ios->power_mode != MMC_POWER_UP)
>>>> +               dw_mci_setup_bus(slot, false);
>>>>
>>> This looks a HACK to me.
>>> If stabilizing host voltage regulator is the problem, can you try out
>>> below patch, and see if this resolve your issue?
>>
>> Actually, IMHO Alim's patch is more of a hack than Addy's.  There's
>> already a 10ms delay between "power up" and "power on" in the MMC core
>> in mmc_power_up() state.  That delay is commented as:
>>
> Well, my suggestion (adding 5ms in switch_volatge) was based on DW_MMC
> databook (V2.41a) section "7.4.1.2 Voltage switch Normal Scenario"
> step #7 which says:" After the 5ms timer expires, the host voltage
> regulator is stable".

if you want to stable power, How about using SDMMC_CMD_INIT flag?

It waits for 80-clock before sending command.(To stable power)
- You can refer to CMD register description.

Best Regards,
Jaehoon Chung

> 
> PS: I have limited to no access of my mails and workstation until
> March 9th, so replies will be slow.
> 
>>   /*
>>    * This delay should be sufficient to allow the power supply
>>    * to reach the minimum voltage.
>>    */
>>   mmc_delay(10);
>>
>> That means that assuming that the voltage is stable in MMC_POWER_UP is
>> not valid anyway.
>>
>>
>> Addy's patch certainly needs more comments.  In another context Olof suggested:
>>
>> /*
>>  * Skip bus setup while voltage is still stabilizing. Instead,
>>  * bus setup will be done at MMC_POWER_ON.
>>  */
>>
>>
>> ...thinking about this more, though: really the voltage should be
>> stabilized when the regulator call returns (see my comments below).
>> In actuality the "right" fix might be to just rearrange this function
>> a little not to turn the clock on _before_ we even try to turn the
>> voltage on.
>>
>> I've got that coded up but I'm still testing it...  If you want to try
>> it too, you can find it at
>> <https://chromium-review.googlesource.com/251341>.
>>
>> Note that without my patch I find that I _really_ need Addy's patch to
>> make sure that the card isn't busy in setup_bus.  With my patch Addy's
>> code catches the card busy less often.  I'm still trying to see if
>> there's a way to totally remove the need for his setup_bus and still
>> trying to grok all the patches flying around...
>>
>>
>>> ===========
>>> [PATCH] mmc: dw_mmc: Wait for host voltage regulator to be stable
>>>
>>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>>> ---
>>>  drivers/mmc/host/dw_mmc.c | 3 +++
>>>  1 file changed, 3 insertions(+)
>>>
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index 4d2e3c2..dc10fbb 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -1202,6 +1202,9 @@ static int dw_mci_switch_voltage(struct mmc_host
>>> *mmc, struct mmc_ios *ios)
>>>   }
>>>   mci_writel(host, UHS_REG, uhs);
>>>
>>> + /* wait for 5ms so that host voltage regulator is stable */
>>> + usleep_range(5000, 5500);
>>> +
>>
>> Alim: if you have some other instance where you actually need VQMMC to
>> stabilize it should probably be done in a different way.  If I
>> understand correctly it is the regulator core's job to make sure that
>> voltage is stable before returning.  If you have a gpio-regulator you
>> may be able to use "startup-delay-us" to specify how long the
>> regulator takes to come up.  You could also look at
>> 'regulator-enable-ramp-delay'
>>
>> -Doug
> 
> 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage
  2015-02-25  7:52             ` Alim Akhtar
  2015-02-25  9:56               ` Jaehoon Chung
@ 2015-02-25 21:05               ` Doug Anderson
  1 sibling, 0 replies; 43+ messages in thread
From: Doug Anderson @ 2015-02-25 21:05 UTC (permalink / raw)
  To: Alim Akhtar
  Cc: Addy Ke, Jaehoon Chung, Ulf Hansson, Olof Johansson,
	Andrzej Hajda, Heiko Stübner, Eddie Cai, lintao, Tao Huang,
	linux-kernel, linux-mmc, linux-arm-kernel,
	open list:ARM/Rockchip SoC...,
	Javier Martinez Canillas

Alim,

On Tue, Feb 24, 2015 at 11:52 PM, Alim Akhtar <alim.akhtar@gmail.com> wrote:
>>> This looks a HACK to me.
>>> If stabilizing host voltage regulator is the problem, can you try out
>>> below patch, and see if this resolve your issue?
>>
>> Actually, IMHO Alim's patch is more of a hack than Addy's.  There's
>> already a 10ms delay between "power up" and "power on" in the MMC core
>> in mmc_power_up() state.  That delay is commented as:
>>
> Well, my suggestion (adding 5ms in switch_volatge) was based on DW_MMC
> databook (V2.41a) section "7.4.1.2 Voltage switch Normal Scenario"
> step #7 which says:" After the 5ms timer expires, the host voltage
> regulator is stable".

So all of that should be handled by the core.  Just reading the DW_MMC
databook can be confusing because they don't differentiate between
what's in the SDMMC spec and what's DW_MMC specific.

Check out mmc_set_signal_voltage(), specifically:

* During a signal voltage level switch, the clock must be gated
* for 5 ms according to the SD spec

-Doug

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2015-02-25 21:05 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-05 11:13 [PATCH] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
2015-02-09  4:51 ` Ulf Hansson
2015-02-09  6:56   ` Addy
2015-02-09  7:04     ` Jaehoon Chung
2015-02-09  9:17       ` addy ke
2015-02-09  7:25 ` [PATCH v2 0/2] about data busy Addy Ke
2015-02-09  7:25   ` [PATCH v2 1/2] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
2015-02-09 10:01     ` Jaehoon Chung
2015-02-11  3:07       ` Addy
2015-02-10 15:22     ` Alim Akhtar
2015-02-11  2:57       ` Addy
2015-02-11 11:58         ` Andrzej Hajda
2015-02-11 23:20           ` Alim Akhtar
2015-02-12  2:28             ` addy ke
2015-02-12 11:10               ` Andrzej Hajda
2015-02-12 13:59                 ` Alim Akhtar
2015-02-13  8:15                   ` addy ke
2015-02-12 11:13             ` Andrzej Hajda
2015-02-12 13:53               ` Alim Akhtar
2015-02-09  7:25   ` [PATCH v2 2/2] mmc: dw_mmc: Don't start command while data busy Addy Ke
2015-02-13 11:52   ` [PATCH v3 0/3] about " Addy Ke
2015-02-13 11:52     ` [PATCH v3 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
2015-02-13 11:52     ` [PATCH v3 2/3] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
2015-02-13 11:52     ` [PATCH v3 3/3] mmc: dw_mmc: Don't start command while data busy Addy Ke
2015-02-14  6:17     ` [PATCH v4 0/3] about " Addy Ke
2015-02-14  6:17       ` [PATCH v4 1/3] mmc: dw_mmc: update clock after host reach a stable voltage Addy Ke
2015-02-15 23:28         ` Alim Akhtar
2015-02-19 10:30           ` addy ke
2015-02-19 23:49           ` Doug Anderson
2015-02-20  0:02             ` Russell King - ARM Linux
2015-02-20  1:04             ` Doug Anderson
2015-02-20 19:05               ` Doug Anderson
2015-02-25  7:52             ` Alim Akhtar
2015-02-25  9:56               ` Jaehoon Chung
2015-02-25 21:05               ` Doug Anderson
2015-02-14  6:17       ` [PATCH v4 2/3] mmc: dw_mmc: fix bug that cause 'Timeout sending command' Addy Ke
2015-02-14  6:17       ` [PATCH v4 3/3] mmc: dw_mmc: Don't start command while data busy Addy Ke
2015-02-20  0:21         ` Doug Anderson
2015-02-15 11:41       ` [PATCH v4 0/3] about " Javier Martinez Canillas
2015-02-16  5:48         ` Jaehoon Chung
2015-02-16 11:09           ` Javier Martinez Canillas
2015-02-19 10:55         ` addy ke
2015-02-20 19:03       ` Doug Anderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).