diff mbox

[RFC] mmc: core: Set clock before switching to highspeed mode.

Message ID 1441448358-13129-1-git-send-email-yszhou4tech@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yousong Zhou Sept. 5, 2015, 10:19 a.m. UTC
A SD card with sunxi-mmc can fail with the following error message (RCD for
response CRC error) when trying to switch to highspeed mode.  Setting the bus
clock before the access mode switch fixed it.

    [    1.112060] mmc0: host does not support reading read-only switch, assuming write-enable
    [    1.120203] ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
    [    1.126527] sunxi-mmc 1c0f000.mmc: smc 0 err, cmd 6, RD RCE !!
    [    1.132388] sunxi-mmc 1c0f000.mmc: data error, sending stop command
    [    1.139451] sunxi-mmc 1c0f000.mmc: send stop command failed
    [    1.145056] mmc0: error -110 whilst initialising SD card
    [    1.150424] ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
    [    1.156533] sunxi-mmc 1c0f000.mmc: smc 0 err, cmd 1, RTO !!

Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
---
 drivers/mmc/core/sd.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Shawn Lin Sept. 5, 2015, 2:07 p.m. UTC | #1
On 2015/9/5 18:19, Yousong Zhou wrote:
> A SD card with sunxi-mmc can fail with the following error message (RCD for
> response CRC error) when trying to switch to highspeed mode.  Setting the bus
> clock before the access mode switch fixed it.

No, that's wrong!

Before this card is switched to highspeed, it works under identification 
mode(From spec: bus clock <= 400KHz). How could you
raise bus clock to higher clk rate which I _guess_ is 52MHz before you 
notify sd cards to run into highspeed mode?

Althought it works for this card, this patch will not please the other 
cards that they might not reply CMDs any longer including the following 
CMD6.


>
>      [    1.112060] mmc0: host does not support reading read-only switch, assuming write-enable
>      [    1.120203] ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
>      [    1.126527] sunxi-mmc 1c0f000.mmc: smc 0 err, cmd 6, RD RCE !!
>      [    1.132388] sunxi-mmc 1c0f000.mmc: data error, sending stop command
>      [    1.139451] sunxi-mmc 1c0f000.mmc: send stop command failed
>      [    1.145056] mmc0: error -110 whilst initialising SD card
>      [    1.150424] ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
>      [    1.156533] sunxi-mmc 1c0f000.mmc: smc 0 err, cmd 1, RTO !!
>
> Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
> ---
>   drivers/mmc/core/sd.c |   10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index 4e7366a..402a8db 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -366,6 +366,11 @@ int mmc_sd_switch_hs(struct mmc_card *card)
>   		return -ENOMEM;
>   	}
>
> +	/*
> +	 * Set bus frequency to match highspeed mode.
> +	 */
> +	mmc_set_clock(card->host, mmc_sd_get_max_clock(card));
> +
>   	err = mmc_sd_switch(card, 1, 0, 1, status);
>   	if (err)
>   		goto out;
> @@ -969,11 +974,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
>   			goto free_card;
>
>   		/*
> -		 * Set bus speed.
> -		 */
> -		mmc_set_clock(host, mmc_sd_get_max_clock(card));
> -
> -		/*
>   		 * Switch to wider bus (if supported).
>   		 */
>   		if ((host->caps & MMC_CAP_4_BIT_DATA) &&
>
Hans de Goede Sept. 5, 2015, 2:58 p.m. UTC | #2
Hi Shawn Lin,

On 05-09-15 16:07, Shawn Lin wrote:
> On 2015/9/5 18:19, Yousong Zhou wrote:
>> A SD card with sunxi-mmc can fail with the following error message (RCD for
>> response CRC error) when trying to switch to highspeed mode.  Setting the bus
>> clock before the access mode switch fixed it.
>
> No, that's wrong!
>
> Before this card is switched to highspeed, it works under identification mode(From spec: bus clock <= 400KHz). How could you
> raise bus clock to higher clk rate which I _guess_ is 52MHz before you notify sd cards to run into highspeed mode?
>
> Althought it works for this card, this patch will not please the other cards that they might not reply CMDs any longer including the following CMD6.

Thanks for the feedback, this is exactly why I asked Yousong Zhou to take this
to the mmc list.

So if this is not the proper fix for the problem that Yousong Zhou is seeing, then
what might be the proper fix ?

Could it be that the sunxi-mmc is doing some things in the wrong order when
changing the clock, or is this all under control of the mmc core ?

Regards,

Hans


>
>
>>
>>      [    1.112060] mmc0: host does not support reading read-only switch, assuming write-enable
>>      [    1.120203] ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
>>      [    1.126527] sunxi-mmc 1c0f000.mmc: smc 0 err, cmd 6, RD RCE !!
>>      [    1.132388] sunxi-mmc 1c0f000.mmc: data error, sending stop command
>>      [    1.139451] sunxi-mmc 1c0f000.mmc: send stop command failed
>>      [    1.145056] mmc0: error -110 whilst initialising SD card
>>      [    1.150424] ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00
>>      [    1.156533] sunxi-mmc 1c0f000.mmc: smc 0 err, cmd 1, RTO !!
>>
>> Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
>> ---
>>   drivers/mmc/core/sd.c |   10 +++++-----
>>   1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
>> index 4e7366a..402a8db 100644
>> --- a/drivers/mmc/core/sd.c
>> +++ b/drivers/mmc/core/sd.c
>> @@ -366,6 +366,11 @@ int mmc_sd_switch_hs(struct mmc_card *card)
>>           return -ENOMEM;
>>       }
>>
>> +    /*
>> +     * Set bus frequency to match highspeed mode.
>> +     */
>> +    mmc_set_clock(card->host, mmc_sd_get_max_clock(card));
>> +
>>       err = mmc_sd_switch(card, 1, 0, 1, status);
>>       if (err)
>>           goto out;
>> @@ -969,11 +974,6 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
>>               goto free_card;
>>
>>           /*
>> -         * Set bus speed.
>> -         */
>> -        mmc_set_clock(host, mmc_sd_get_max_clock(card));
>> -
>> -        /*
>>            * Switch to wider bus (if supported).
>>            */
>>           if ((host->caps & MMC_CAP_4_BIT_DATA) &&
>>
>
>
--
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
Shawn Lin Sept. 6, 2015, 12:12 a.m. UTC | #3
On 2015/9/5 22:58, Hans de Goede wrote:
> Hi Shawn Lin,
>
> On 05-09-15 16:07, Shawn Lin wrote:
>> On 2015/9/5 18:19, Yousong Zhou wrote:
>>> A SD card with sunxi-mmc can fail with the following error message
>>> (RCD for
>>> response CRC error) when trying to switch to highspeed mode.  Setting
>>> the bus
>>> clock before the access mode switch fixed it.
>>
>> No, that's wrong!
>>
>> Before this card is switched to highspeed, it works under
>> identification mode(From spec: bus clock <= 400KHz). How could you
>> raise bus clock to higher clk rate which I _guess_ is 52MHz before you
>> notify sd cards to run into highspeed mode?
>>
>> Althought it works for this card, this patch will not please the other
>> cards that they might not reply CMDs any longer including the
>> following CMD6.
>
> Thanks for the feedback, this is exactly why I asked Yousong Zhou to
> take this
> to the mmc list.
>
> So if this is not the proper fix for the problem that Yousong Zhou is
> seeing, then
> what might be the proper fix ?
>

 From my knowledge of mmc, there hadn't have a way to deal with this 
"broken" case. In another word, IMO,it's ANTI-SPEC. We can't be too spec 
sometimes, but at least we shouldn't violate it.

> Could it be that the sunxi-mmc is doing some things in the wrong order when
> changing the clock, or is this all under control of the mmc core ?
>

all of this is under control of the mmc core.
So if Yongsong does want this card to work for any linux-based mmc 
stack, I guess something like that should be "better"?

if (switch to HS fail) {
	set_bus_clk
	goto retry switch to HS
}

BUT...I admit it seems strange as well.


> Regards,
>
> Hans
>
>
>>
>>
>>>
>>>      [    1.112060] mmc0: host does not support reading read-only
>>> switch, assuming write-enable
>>>      [    1.120203] ehci-platform 1c1c000.usb: irq 31, io mem 0x01c1c000
>>>      [    1.126527] sunxi-mmc 1c0f000.mmc: smc 0 err, cmd 6, RD RCE !!
>>>      [    1.132388] sunxi-mmc 1c0f000.mmc: data error, sending stop
>>> command
>>>      [    1.139451] sunxi-mmc 1c0f000.mmc: send stop command failed
>>>      [    1.145056] mmc0: error -110 whilst initialising SD card
>>>      [    1.150424] ehci-platform 1c1c000.usb: USB 2.0 started, EHCI
>>> 1.00
>>>      [    1.156533] sunxi-mmc 1c0f000.mmc: smc 0 err, cmd 1, RTO !!
>>>
>>> Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
>>> ---
>>>   drivers/mmc/core/sd.c |   10 +++++-----
>>>   1 file changed, 5 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
>>> index 4e7366a..402a8db 100644
>>> --- a/drivers/mmc/core/sd.c
>>> +++ b/drivers/mmc/core/sd.c
>>> @@ -366,6 +366,11 @@ int mmc_sd_switch_hs(struct mmc_card *card)
>>>           return -ENOMEM;
>>>       }
>>>
>>> +    /*
>>> +     * Set bus frequency to match highspeed mode.
>>> +     */
>>> +    mmc_set_clock(card->host, mmc_sd_get_max_clock(card));
>>> +
>>>       err = mmc_sd_switch(card, 1, 0, 1, status);
>>>       if (err)
>>>           goto out;
>>> @@ -969,11 +974,6 @@ static int mmc_sd_init_card(struct mmc_host
>>> *host, u32 ocr,
>>>               goto free_card;
>>>
>>>           /*
>>> -         * Set bus speed.
>>> -         */
>>> -        mmc_set_clock(host, mmc_sd_get_max_clock(card));
>>> -
>>> -        /*
>>>            * Switch to wider bus (if supported).
>>>            */
>>>           if ((host->caps & MMC_CAP_4_BIT_DATA) &&
>>>
>>
>>
>
>
>
Yousong Zhou Sept. 6, 2015, 12:09 p.m. UTC | #4
Hi,

On 6 September 2015 at 08:12, Shawn Lin <shawn.lin@rock-chips.com> wrote:
> On 2015/9/5 22:58, Hans de Goede wrote:
>>
>> Hi Shawn Lin,
>>
>> On 05-09-15 16:07, Shawn Lin wrote:
>>>
>>> On 2015/9/5 18:19, Yousong Zhou wrote:
>>>>
>>>> A SD card with sunxi-mmc can fail with the following error message
>>>> (RCD for
>>>> response CRC error) when trying to switch to highspeed mode.  Setting
>>>> the bus
>>>> clock before the access mode switch fixed it.
>>>
>>>
>>> No, that's wrong!
>>>
>>> Before this card is switched to highspeed, it works under
>>> identification mode(From spec: bus clock <= 400KHz). How could you
>>> raise bus clock to higher clk rate which I _guess_ is 52MHz before you
>>> notify sd cards to run into highspeed mode?
>>>
>>> Althought it works for this card, this patch will not please the other
>>> cards that they might not reply CMDs any longer including the
>>> following CMD6.
>>
>>
>> Thanks for the feedback, this is exactly why I asked Yousong Zhou to
>> take this
>> to the mmc list.
>>
>> So if this is not the proper fix for the problem that Yousong Zhou is
>> seeing, then
>> what might be the proper fix ?
>>
>
> From my knowledge of mmc, there hadn't have a way to deal with this "broken"
> case. In another word, IMO,it's ANTI-SPEC. We can't be too spec sometimes,
> but at least we shouldn't violate it.
>

Maybe the fix is anti-spec.  But the fact is that the card works on
many other platforms with the builtin card reader (not through an USB
adapter), including Mac OS X, my old Nokia Symbian phone, and Windows.

>> Could it be that the sunxi-mmc is doing some things in the wrong order
>> when
>> changing the clock, or is this all under control of the mmc core ?
>>
>
> all of this is under control of the mmc core.
> So if Yongsong does want this card to work for any linux-based mmc stack, I
> guess something like that should be "better"?
>
> if (switch to HS fail) {
>         set_bus_clk
>         goto retry switch to HS
> }
>
> BUT...I admit it seems strange as well.
>

The SD Specification (simplified version) says "If CRC error occurs on
the status data, the host should issue a power cycle.", so I guess the
above approach is anti-spec in some way :)

In case it may help debug this problem, I'd like to add that the card
previously worked fine with U-Boot before commit [1].  This can also
be confirmed by Debian Jessie installer image with which the old
U-Boot there worked fine while the kernel (3.16) did not.

 [1] sunxi: mmc: Properly setup mod-clk and clock sampling phases,
http://git.denx.de/?p=u-boot.git;a=commit;h=fc3a832576ce7bb597b1823935bfb7dcca235c3c

Cheers

                yousong
--
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
Shawn Lin Sept. 6, 2015, 2:14 p.m. UTC | #5
? 2015/9/6 20:09, Yousong Zhou ??:
> Hi,
>
> On 6 September 2015 at 08:12, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>> On 2015/9/5 22:58, Hans de Goede wrote:
>>>
>>> Hi Shawn Lin,
>>>
>>> On 05-09-15 16:07, Shawn Lin wrote:
>>>>
>>>> On 2015/9/5 18:19, Yousong Zhou wrote:
>>>>>
>>>>> A SD card with sunxi-mmc can fail with the following error message
>>>>> (RCD for
>>>>> response CRC error) when trying to switch to highspeed mode.  Setting
>>>>> the bus
>>>>> clock before the access mode switch fixed it.
>>>>
>>>>
>>>> No, that's wrong!
>>>>
>>>> Before this card is switched to highspeed, it works under
>>>> identification mode(From spec: bus clock <= 400KHz). How could you
>>>> raise bus clock to higher clk rate which I _guess_ is 52MHz before you
>>>> notify sd cards to run into highspeed mode?
>>>>
>>>> Althought it works for this card, this patch will not please the other
>>>> cards that they might not reply CMDs any longer including the
>>>> following CMD6.
>>>
>>>
>>> Thanks for the feedback, this is exactly why I asked Yousong Zhou to
>>> take this
>>> to the mmc list.
>>>
>>> So if this is not the proper fix for the problem that Yousong Zhou is
>>> seeing, then
>>> what might be the proper fix ?
>>>
>>
>>  From my knowledge of mmc, there hadn't have a way to deal with this "broken"
>> case. In another word, IMO,it's ANTI-SPEC. We can't be too spec sometimes,
>> but at least we shouldn't violate it.
>>
>
> Maybe the fix is anti-spec.  But the fact is that the card works on
> many other platforms with the builtin card reader (not through an USB
> adapter), including Mac OS X, my old Nokia Symbian phone, and Windows.
>
>>> Could it be that the sunxi-mmc is doing some things in the wrong order
>>> when
>>> changing the clock, or is this all under control of the mmc core ?
>>>
>>
>> all of this is under control of the mmc core.
>> So if Yongsong does want this card to work for any linux-based mmc stack, I
>> guess something like that should be "better"?
>>
>> if (switch to HS fail) {
>>          set_bus_clk
>>          goto retry switch to HS
>> }
>>
>> BUT...I admit it seems strange as well.
>>
>
> The SD Specification (simplified version) says "If CRC error occurs on
> the status data, the host should issue a power cycle.", so I guess the
> above approach is anti-spec in some way :)
>

Right?I was guessing that way from your intention.

> In case it may help debug this problem, I'd like to add that the card
> previously worked fine with U-Boot before commit [1].  This can also
> be confirmed by Debian Jessie installer image with which the old
> U-Boot there worked fine while the kernel (3.16) did not.
>
>   [1] sunxi: mmc: Properly setup mod-clk and clock sampling phases,
> http://git.denx.de/?p=u-boot.git;a=commit;h=fc3a832576ce7bb597b1823935bfb7dcca235c3c
>

Interesting... but that at least prove your patch is a workaround but 
not find the root cause.

Anyway, look into commit-sha [1], can you have a test by restoring 
mod-clk and clock sampling phases before jump to kernel.

I happended to fix some problems which seems *similar* to yours(but I'm 
not sure just from commit[1]'s msg):

https://patchwork.kernel.org/patch/7119661/

> Cheers
>
>                  yousong
> --
> 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
>
>
>
Yousong Zhou Sept. 6, 2015, 2:51 p.m. UTC | #6
>>> all of this is under control of the mmc core.
>>> So if Yongsong does want this card to work for any linux-based mmc stack,
>>> I
>>> guess something like that should be "better"?
>>>
>>> if (switch to HS fail) {
>>>          set_bus_clk
>>>          goto retry switch to HS
>>> }
>>>
>>> BUT...I admit it seems strange as well.
>>>
>>
>> The SD Specification (simplified version) says "If CRC error occurs on
>> the status data, the host should issue a power cycle.", so I guess the
>> above approach is anti-spec in some way :)
>>
>
> Right?I was guessing that way from your intention.
>
>> In case it may help debug this problem, I'd like to add that the card
>> previously worked fine with U-Boot before commit [1].  This can also
>> be confirmed by Debian Jessie installer image with which the old
>> U-Boot there worked fine while the kernel (3.16) did not.
>>
>>   [1] sunxi: mmc: Properly setup mod-clk and clock sampling phases,
>>
>> http://git.denx.de/?p=u-boot.git;a=commit;h=fc3a832576ce7bb597b1823935bfb7dcca235c3c
>>
>
> Interesting... but that at least prove your patch is a workaround but not
> find the root cause.
>
> Anyway, look into commit-sha [1], can you have a test by restoring mod-clk
> and clock sampling phases before jump to kernel.
>

Maybe my statement about U-Boot commit [1] above was a little
ambiguous, sorry.  I meant to say that with that commit applied,
U-Boot failed initialising the card the same way as the kernel, i.e.
response crc error.

The Debian Jessie installer image's U-Boot worked fine and booted the
kernel because it was before commit [1] happened.  However after that
the 3.16 kernel failed initialising the card.

So, with commit [1], U-Boot failed right away without any chance at
all jumping to kernel.

OpenWrt ticket 20387 has more info about the U-Boot failure.

https://dev.openwrt.org/ticket/20387

Anyway, I have no idea what's the effect of those magic numbers on
"sampling phases".  Never played with such things before :)

                yousong

> I happended to fix some problems which seems *similar* to yours(but I'm not
> sure just from commit[1]'s msg):
>
> https://patchwork.kernel.org/patch/7119661/
--
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
Shawn Lin Sept. 7, 2015, 12:16 a.m. UTC | #7
On 2015/9/6 22:51, Yousong Zhou wrote:
>>>> all of this is under control of the mmc core.
>>>> So if Yongsong does want this card to work for any linux-based mmc stack,
>>>> I
>>>> guess something like that should be "better"?
>>>>
>>>> if (switch to HS fail) {
>>>>           set_bus_clk
>>>>           goto retry switch to HS
>>>> }
>>>>
>>>> BUT...I admit it seems strange as well.
>>>>
>>>
>>> The SD Specification (simplified version) says "If CRC error occurs on
>>> the status data, the host should issue a power cycle.", so I guess the
>>> above approach is anti-spec in some way :)
>>>
>>
>> Right?I was guessing that way from your intention.
>>
>>> In case it may help debug this problem, I'd like to add that the card
>>> previously worked fine with U-Boot before commit [1].  This can also
>>> be confirmed by Debian Jessie installer image with which the old
>>> U-Boot there worked fine while the kernel (3.16) did not.
>>>
>>>    [1] sunxi: mmc: Properly setup mod-clk and clock sampling phases,
>>>
>>> http://git.denx.de/?p=u-boot.git;a=commit;h=fc3a832576ce7bb597b1823935bfb7dcca235c3c
>>>
>>
>> Interesting... but that at least prove your patch is a workaround but not
>> find the root cause.
>>
>> Anyway, look into commit-sha [1], can you have a test by restoring mod-clk
>> and clock sampling phases before jump to kernel.
>>
>
> Maybe my statement about U-Boot commit [1] above was a little
> ambiguous, sorry.  I meant to say that with that commit applied,
> U-Boot failed initialising the card the same way as the kernel, i.e.
> response crc error.
>
> The Debian Jessie installer image's U-Boot worked fine and booted the
> kernel because it was before commit [1] happened.  However after that
> the 3.16 kernel failed initialising the card.
>

So I undertand your point:  Uboot w/o commit[1] + 3.16 kernel failed 
that way just as Uboot w/ commit[1] + pre-3.16 kernel, right?

If that is it, could you check sunxi-platform's patches merged into 
v3.16 for sure whether there is any patch do the same things just like 
what commit[1] did for uboot or not?

> So, with commit [1], U-Boot failed right away without any chance at
> all jumping to kernel.
>
> OpenWrt ticket 20387 has more info about the U-Boot failure.
>
> https://dev.openwrt.org/ticket/20387
>
> Anyway, I have no idea what's the effect of those magic numbers on
> "sampling phases".  Never played with such things before :)
>
>                  yousong
>
>> I happended to fix some problems which seems *similar* to yours(but I'm not
>> sure just from commit[1]'s msg):
>>
>> https://patchwork.kernel.org/patch/7119661/
>
>
>
diff mbox

Patch

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 4e7366a..402a8db 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -366,6 +366,11 @@  int mmc_sd_switch_hs(struct mmc_card *card)
 		return -ENOMEM;
 	}
 
+	/*
+	 * Set bus frequency to match highspeed mode.
+	 */
+	mmc_set_clock(card->host, mmc_sd_get_max_clock(card));
+
 	err = mmc_sd_switch(card, 1, 0, 1, status);
 	if (err)
 		goto out;
@@ -969,11 +974,6 @@  static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
 			goto free_card;
 
 		/*
-		 * Set bus speed.
-		 */
-		mmc_set_clock(host, mmc_sd_get_max_clock(card));
-
-		/*
 		 * Switch to wider bus (if supported).
 		 */
 		if ((host->caps & MMC_CAP_4_BIT_DATA) &&