2010-01-01 23:11:18

by Ben Nizette

[permalink] [raw]
Subject: [PATCH v2] mmc: lower init clock frequency to 300kHz


A good few months ago, commit

commit 8dfd0374be84793360db7fff2e635d2cd3bbcb21
Author: Sascha Hauer <[email protected]>
Date: Thu Apr 9 08:32:02 2009 +0200

MMC core: limit minimum initialization frequency to 400kHz

broke a few setups with cards which don't quite adhere to the MMC spec - 400kHz is just too fast for them. In my testing, all of the cards which fail at 400kHz are OK by about 350Khz but this patch drops the floor to 300 to be on the safe side.

Dropping the floor also means that the warning will trigger on some valid setups, albeit ones which won't run particularly crappy cards. This patch then slightly softens the language of said warning to make it clear it isn't always a problem.

V1 of this patch dropped the floor all the way to 50kHz on the basis that it was only for a few 100 bytes so that very low speed shouldn't matter. After some discussion [1] the consensus was that 50 was too slow after all so this patch is a bit more sensible.

Signed-off-by: Ben Nizette <[email protected]>

[1] http://lkml.org/lkml/2009/7/1/529

---
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7dab2e5..49f0eae 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -891,12 +891,12 @@ static void mmc_power_up(struct mmc_host *host)
*/
mmc_delay(10);

- if (host->f_min > 400000) {
- pr_warning("%s: Minimum clock frequency too high for "
+ if (host->f_min > 300000) {
+ pr_warning("%s: Minimum clock frequency may be too high for "
"identification mode\n", mmc_hostname(host));
host->ios.clock = host->f_min;
} else
- host->ios.clock = 400000;
+ host->ios.clock = 300000;

host->ios.power_mode = MMC_POWER_ON;
mmc_set_ios(host);


2010-01-02 09:07:18

by Ben Nizette

[permalink] [raw]
Subject: Re: [PATCH v2] mmc: lower init clock frequency to 300kHz


(Adding linux CCs)

On 02/01/2010, at 7:19 PM, Hein_Tibosch wrote:

> Almost good: on my Kingston Elite Pro (50x) SD-card, initialization will
> only succeed if F <= 282258 Hz.

...

>
> I checked some datasheets of several makes:
>
> Delkin microSD min 0 max 400
> Swissbit min 0 max 400
> Sandisk 100 - 400
> Toshiba 100 - 400
> ST electronics 0 400
> SD-specification: Issue continues clock in frequency range of 100KHz-400KHz
> If the Average frequency of the SDCLK is less than 100KHz then the card
> may not be able to respond within the 1-second limit
>
> So what about 100 or 150 Khz?

Ah geez, yeah this something else I was hoping to avoid with the V1 patch - an endless stream of "oh shit, this card's even /moore/ broken! Patch it, patch it good"

Pierre, thoughts? All my cards were borderline spec but Hein's got a mainstream, common card which seems to completely ignore the spec. Can we just take the few-hundred-uS hit and allow initialization down at the bottom end, say 100kHz?

<overkill> Or a KConfig option? </overkill>

--Ben.

2010-01-02 23:38:12

by Pierre Ossman

[permalink] [raw]
Subject: Re: [PATCH v3] mmc: Make ID freq configurable

On Sun, 3 Jan 2010 09:23:30 +1100
Ben Nizette <[email protected]> wrote:

> >
> > Broken cards seem to be all over the spectrum, so I wouldn't be
> > suprised if you find ones that break if you go too low as well.
>
> Yea good point, though given there might not even be a One Freq to Rule Them All, how about:
>
> ---8<---
>
> From: Ben Nizette <[email protected]>
> Subject: [PATCH v3] mmc: Make ID freq configurable
>
> While the SD spec specifies a range of frequencies for the ID phase from 100-400kHz, not all cards play by the rules. This patch adds a Kconfig option to allow the user to tweak this to their card/host config, though the default of 250kHz should be fine for all spec-abiding cards and most others besides.
>
> Signed-off-by: Ben Nizette <[email protected]>
>

This is not a good solution. We all use the same pool of cards so we
should all be using the same init sequence. If there isn't a single
frequency where all cards will work, then we'll have to make something
more advanced where the kernel will try the init several times with
different clocking.

Rgds
--
-- Pierre Ossman

WARNING: This correspondence is being monitored by FRA, a
Swedish intelligence agency. Make sure your server uses
encryption for SMTP traffic and consider using PGP for
end-to-end encryption.


Attachments:
signature.asc (198.00 B)

2010-01-02 22:23:40

by Ben Nizette

[permalink] [raw]
Subject: [PATCH v3] mmc: Make ID freq configurable


On 02/01/2010, at 11:08 PM, Pierre Ossman wrote:

> On Sat, 2 Jan 2010 20:07:01 +1100
> Ben Nizette <[email protected]> wrote:
>
>>
>> Pierre, thoughts? All my cards were borderline spec but Hein's got a mainstream, common card which seems to completely ignore the spec. Can we just take the few-hundred-uS hit and allow initialization down at the bottom end, say 100kHz?
>>
>
> Broken cards seem to be all over the spectrum, so I wouldn't be
> suprised if you find ones that break if you go too low as well.

Yea good point, though given there might not even be a One Freq to Rule Them All, how about:

---8<---

From: Ben Nizette <[email protected]>
Subject: [PATCH v3] mmc: Make ID freq configurable

While the SD spec specifies a range of frequencies for the ID phase from 100-400kHz, not all cards play by the rules. This patch adds a Kconfig option to allow the user to tweak this to their card/host config, though the default of 250kHz should be fine for all spec-abiding cards and most others besides.

Signed-off-by: Ben Nizette <[email protected]>

---
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index ab37a6d..a8e5003 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -14,3 +14,15 @@ config MMC_UNSAFE_RESUME
This option is usually just for embedded systems which use
a MMC/SD card for rootfs. Most people should say N here.

+config MMC_ID_FREQ
+ int "SD/MMC Card initialisation frequency (Hz)"
+ default 250000
+ help
+ The SD card specification allows for initialisation
+ frequencies from 100-400kHz however some broken cards are
+ known not to work across this whole range.
+
+ If you're having problems with a particular card not being
+ detected, you may try adjusting this frequency up or down
+ but for widest compatibility just leave it default.
+
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7dab2e5..2eab68f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -891,12 +891,17 @@ static void mmc_power_up(struct mmc_host *host)
*/
mmc_delay(10);

- if (host->f_min > 400000) {
- pr_warning("%s: Minimum clock frequency too high for "
- "identification mode\n", mmc_hostname(host));
+ /*
+ * CONFIG_MMC_ID_FREQ defaults to 250kHz which should be fine
+ * for most card/host combos.
+ */
+ if (host->f_min > CONFIG_MMC_ID_FREQ) {
+ pr_warning("%s: The host cannot reach the requested ID clock "
+ "rate, identification may fail\n",
+ mmc_hostname(host));
host->ios.clock = host->f_min;
} else
- host->ios.clock = 400000;
+ host->ios.clock = CONFIG_MMC_ID_FREQ;

host->ios.power_mode = MMC_POWER_ON;
mmc_set_ios(host);

2010-01-02 12:08:18

by Pierre Ossman

[permalink] [raw]
Subject: Re: [PATCH v2] mmc: lower init clock frequency to 300kHz

On Sat, 2 Jan 2010 20:07:01 +1100
Ben Nizette <[email protected]> wrote:

>
> Pierre, thoughts? All my cards were borderline spec but Hein's got a mainstream, common card which seems to completely ignore the spec. Can we just take the few-hundred-uS hit and allow initialization down at the bottom end, say 100kHz?
>

Broken cards seem to be all over the spectrum, so I wouldn't be
suprised if you find ones that break if you go too low as well.

Basically you'll just have to try something and watch the bug reports.
Perhaps doing the bisect approach and choosing the intermediate value
each time? I.e. halvway between 400 and 100 for now (250). If that is
too fast, then halway between that and 100 (175), and so on.

Rgds
--
-- Pierre Ossman

WARNING: This correspondence is being monitored by FRA, a
Swedish intelligence agency. Make sure your server uses
encryption for SMTP traffic and consider using PGP for
end-to-end encryption.


Attachments:
signature.asc (198.00 B)

2010-01-02 23:04:14

by Robert Hancock

[permalink] [raw]
Subject: Re: [PATCH v3] mmc: Make ID freq configurable

On 01/02/2010 04:23 PM, Ben Nizette wrote:
>
> On 02/01/2010, at 11:08 PM, Pierre Ossman wrote:
>
>> On Sat, 2 Jan 2010 20:07:01 +1100
>> Ben Nizette<[email protected]> wrote:
>>
>>>
>>> Pierre, thoughts? All my cards were borderline spec but Hein's got a mainstream, common card which seems to completely ignore the spec. Can we just take the few-hundred-uS hit and allow initialization down at the bottom end, say 100kHz?
>>>
>>
>> Broken cards seem to be all over the spectrum, so I wouldn't be
>> suprised if you find ones that break if you go too low as well.
>
> Yea good point, though given there might not even be a One Freq to Rule Them All, how about:
>
> ---8<---
>
> From: Ben Nizette<[email protected]>
> Subject: [PATCH v3] mmc: Make ID freq configurable
>
> While the SD spec specifies a range of frequencies for the ID phase from 100-400kHz, not all cards play by the rules. This patch adds a Kconfig option to allow the user to tweak this to their card/host config, though the default of 250kHz should be fine for all spec-abiding cards and most others besides.
>
> Signed-off-by: Ben Nizette<[email protected]>
>
> ---
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index ab37a6d..a8e5003 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -14,3 +14,15 @@ config MMC_UNSAFE_RESUME
> This option is usually just for embedded systems which use
> a MMC/SD card for rootfs. Most people should say N here.
>
> +config MMC_ID_FREQ
> + int "SD/MMC Card initialisation frequency (Hz)"
> + default 250000
> + help
> + The SD card specification allows for initialisation
> + frequencies from 100-400kHz however some broken cards are
> + known not to work across this whole range.
> +
> + If you're having problems with a particular card not being
> + detected, you may try adjusting this frequency up or down
> + but for widest compatibility just leave it default.

Don't know that a kconfig option is best for this, it'd suck to have to
recompile the kernel to change it. Module option might be better..

2010-01-03 08:01:30

by Hein_Tibosch

[permalink] [raw]
Subject: Re: [PATCH v3] mmc: Make ID freq configurable

Pierre Ossman wrote:
> On Sun, 3 Jan 2010 09:23:30 +1100
> Ben Nizette <[email protected]> wrote:
>
>
>>> Broken cards seem to be all over the spectrum, so I wouldn't be
>>> suprised if you find ones that break if you go too low as well.
>>>
>> Yea good point, though given there might not even be a One Freq to Rule Them All, how about:
>>
>> ---8<---
>>
>> From: Ben Nizette <[email protected]>
>> Subject: [PATCH v3] mmc: Make ID freq configurable
>>
>> While the SD spec specifies a range of frequencies for the ID phase from 100-400kHz, not all cards play by the rules. This patch adds a Kconfig option to allow the user to tweak this to their card/host config, though the default of 250kHz should be fine for all spec-abiding cards and most others besides.
>>
>> Signed-off-by: Ben Nizette <[email protected]>
>>
>>
>
> This is not a good solution. We all use the same pool of cards so we
> should all be using the same init sequence. If there isn't a single
> frequency where all cards will work, then we'll have to make something
> more advanced where the kernel will try the init several times with
> different clocking.
>
As I'm lucky to have main-stream cards that break the rule (on
avr32/AP7) I'll dive deeper into it and see if I can make it "automatic"
so that initialization will work for any of cards. Indeed using a kind
of 'bisect approach' approach.
... although I must say that before Sascha Hauer's patch, we never had
problems with any of the cards, using the controller's minimum freq of
137 Khz.

Hein


2010-01-04 21:08:26

by Hein_Tibosch

[permalink] [raw]
Subject: Re: [PATCH v3] mmc: Make ID freq configurable

On 3-1-2010 07:38, Pierre Ossman wrote:
>
> <cut>
> We all use the same pool of cards so we
> should all be using the same init sequence. If there isn't a single
> frequency where all cards will work, then we'll have to make something
> more advanced where the kernel will try the init several times with
> different clocking.

On 4-1-2010 20:15, Sascha Hauer wrote:
> The problem was that in some setups the mxcmmc driver allows frequencies
> as low as a few Hz and the card initialization took ages. Increasing the
> frequency to 400kHz seemed sensible since it's the value the spec
> describes. 50kHz should be fine as well.
>

I tried out several main-stream sd-cards and with the Atmel (AP7) controller
they all initialize with F between 138 (=f_min) and 280 Khz.

Below a patch which tries mmc-initialization using several frequencies
from an array 400, 300, 200 and 100. When it comes to 200 Khz, it works.
The two failed attempts lasted about 10 ms together.

It looks like a hell-of-a-patch but that's because the indentation changes.

Note that the new mmc_host member f_init will be used later in power_restore
and resume. As power_up always comes first, it should have a descend value
by then.

But I still wonder, why not just keep using Sascha's patch, changing 400000
to 50000? Has anyone ever had problems with mmc-init on 50 Khz?


Signed-off-by: Hein Tibosch <[email protected]>

---
diff -Nurp a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -891,12 +891,7 @@ static void mmc_power_up(struct mmc_host
*/
mmc_delay(10);

- if (host->f_min > 400000) {
- pr_warning("%s: Minimum clock frequency too high for "
- "identification mode\n", mmc_hostname(host));
- host->ios.clock = host->f_min;
- } else
- host->ios.clock = 400000;
+ host->ios.clock = host->f_init;

host->ios.power_mode = MMC_POWER_ON;
mmc_set_ios(host);
@@ -1041,6 +1036,8 @@ void mmc_rescan(struct work_struct *work
container_of(work, struct mmc_host, detect.work);
u32 ocr;
int err;
+ int i;
+ unsigned freqs[] = { 400000, 300000, 200000, 100000 };

mmc_bus_get(host);

@@ -1070,46 +1067,55 @@ void mmc_rescan(struct work_struct *work
if (host->ops->get_cd && host->ops->get_cd(host) == 0)
goto out;

- mmc_claim_host(host);
+ for (i = 0; i < ARRAY_SIZE(freqs); i++) {
+ mmc_claim_host(host);

- mmc_power_up(host);
- mmc_go_idle(host);
+ if (freqs[i] >= host->f_min)
+ host->f_init = freqs[i];
+ else if (i && freqs[i-1] <= host->f_min)
+ goto out;
+ else
+ host->f_init = host->f_min;

- mmc_send_if_cond(host, host->ocr_avail);
+ printk ("mmc_rescan: trying %u Hz\n", host->f_init);
+ mmc_power_up(host);
+ mmc_go_idle(host);

- /*
- * First we search for SDIO...
- */
- err = mmc_send_io_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_sdio(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ mmc_send_if_cond(host, host->ocr_avail);

- /*
- * ...then normal SD...
- */
- err = mmc_send_app_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_sd(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ /*
+ * First we search for SDIO...
+ */
+ err = mmc_send_io_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_sdio(host, ocr))
+ mmc_power_off(host);
+ goto out;
+ }

- /*
- * ...and finally MMC.
- */
- err = mmc_send_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_mmc(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ /*
+ * ...then normal SD...
+ */
+ err = mmc_send_app_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_sd(host, ocr))
+ mmc_power_off(host);
+ goto out;
+ }

- mmc_release_host(host);
- mmc_power_off(host);
+ /*
+ * ...and finally MMC.
+ */
+ err = mmc_send_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_mmc(host, ocr))
+ mmc_power_off(host);
+ goto out;
+ }

+ mmc_release_host(host);
+ mmc_power_off(host);
+ }
out:
if (host->caps & MMC_CAP_NEEDS_POLL)
mmc_schedule_delayed_work(&host->detect, HZ);
diff -Nurp a/include/linux/mmc/host.h b/include/linux/mmc/host.h
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -119,6 +119,7 @@ struct mmc_host {
const struct mmc_host_ops *ops;
unsigned int f_min;
unsigned int f_max;
+ unsigned int f_init;
u32 ocr_avail;

#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */




2010-01-04 22:01:08

by Hein_Tibosch

[permalink] [raw]
Subject: Re: [PATCH v3] mmc: Make ID freq configurable


In my last mail the spaces in the patch were mistreated, sorry for that.

Below a patch which tries mmc-initialization using several frequencies
from an array 400, 300, 200 and 100.


Signed-off-by: Hein Tibosch <[email protected]>

---
diff -Nurp a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -891,12 +891,7 @@ static void mmc_power_up(struct mmc_host
*/
mmc_delay(10);

- if (host->f_min > 400000) {
- pr_warning("%s: Minimum clock frequency too high for "
- "identification mode\n", mmc_hostname(host));
- host->ios.clock = host->f_min;
- } else
- host->ios.clock = 400000;
+ host->ios.clock = host->f_init;

host->ios.power_mode = MMC_POWER_ON;
mmc_set_ios(host);
@@ -1041,6 +1036,8 @@ void mmc_rescan(struct work_struct *work
container_of(work, struct mmc_host, detect.work);
u32 ocr;
int err;
+ int i;
+ unsigned freqs[] = { 400000, 300000, 200000, 100000 };

mmc_bus_get(host);

@@ -1070,46 +1067,55 @@ void mmc_rescan(struct work_struct *work
if (host->ops->get_cd && host->ops->get_cd(host) == 0)
goto out;

- mmc_claim_host(host);
+ for (i = 0; i < ARRAY_SIZE(freqs); i++) {
+ mmc_claim_host(host);

- mmc_power_up(host);
- mmc_go_idle(host);
+ if (freqs[i] >= host->f_min)
+ host->f_init = freqs[i];
+ else if (i && freqs[i-1] <= host->f_min)
+ goto out;
+ else
+ host->f_init = host->f_min;

- mmc_send_if_cond(host, host->ocr_avail);
+ printk ("mmc_rescan: trying %u Hz\n", host->f_init);
+ mmc_power_up(host);
+ mmc_go_idle(host);

- /*
- * First we search for SDIO...
- */
- err = mmc_send_io_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_sdio(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ mmc_send_if_cond(host, host->ocr_avail);

- /*
- * ...then normal SD...
- */
- err = mmc_send_app_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_sd(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ /*
+ * First we search for SDIO...
+ */
+ err = mmc_send_io_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_sdio(host, ocr))
+ mmc_power_off(host);
+ goto out;
+ }

- /*
- * ...and finally MMC.
- */
- err = mmc_send_op_cond(host, 0, &ocr);
- if (!err) {
- if (mmc_attach_mmc(host, ocr))
- mmc_power_off(host);
- goto out;
- }
+ /*
+ * ...then normal SD...
+ */
+ err = mmc_send_app_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_sd(host, ocr))
+ mmc_power_off(host);
+ goto out;
+ }

- mmc_release_host(host);
- mmc_power_off(host);
+ /*
+ * ...and finally MMC.
+ */
+ err = mmc_send_op_cond(host, 0, &ocr);
+ if (!err) {
+ if (mmc_attach_mmc(host, ocr))
+ mmc_power_off(host);
+ goto out;
+ }

+ mmc_release_host(host);
+ mmc_power_off(host);
+ }
out:
if (host->caps & MMC_CAP_NEEDS_POLL)
mmc_schedule_delayed_work(&host->detect, HZ);
diff -Nurp a/include/linux/mmc/host.h b/include/linux/mmc/host.h
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -119,6 +119,7 @@ struct mmc_host {
const struct mmc_host_ops *ops;
unsigned int f_min;
unsigned int f_max;
+ unsigned int f_init;
u32 ocr_avail;

#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */

2010-01-05 12:24:38

by Sascha Hauer

[permalink] [raw]
Subject: Re: [PATCH v3] mmc: Make ID freq configurable

On Tue, Jan 05, 2010 at 05:07:21AM +0800, Hein_Tibosch wrote:
> On 3-1-2010 07:38, Pierre Ossman wrote:
>>
>> <cut>
>> We all use the same pool of cards so we
>> should all be using the same init sequence. If there isn't a single
>> frequency where all cards will work, then we'll have to make something
>> more advanced where the kernel will try the init several times with
>> different clocking.
>
> On 4-1-2010 20:15, Sascha Hauer wrote:
>> The problem was that in some setups the mxcmmc driver allows frequencies
>> as low as a few Hz and the card initialization took ages. Increasing the
>> frequency to 400kHz seemed sensible since it's the value the spec
>> describes. 50kHz should be fine as well.
>>
>
> I tried out several main-stream sd-cards and with the Atmel (AP7) controller
> they all initialize with F between 138 (=f_min) and 280 Khz.
>
> Below a patch which tries mmc-initialization using several frequencies
> from an array 400, 300, 200 and 100. When it comes to 200 Khz, it works.
> The two failed attempts lasted about 10 ms together.
>
> It looks like a hell-of-a-patch but that's because the indentation changes.
>
> Note that the new mmc_host member f_init will be used later in power_restore
> and resume. As power_up always comes first, it should have a descend value
> by then.
>
> But I still wonder, why not just keep using Sascha's patch, changing 400000
> to 50000? Has anyone ever had problems with mmc-init on 50 Khz?

I already wrote it to Hein in private, once again for the rest:

The original reason to increase the minimum frequency was that the
Freescale i.MX MMC core allows minimum frequencies of just a few Hz.
With this the card initialisation took ages, so we increased the minimum
frequency. 400kHz seemed like a good value since all cards should
support this, but I'm also fine with any other value between 50kHz and
400kHz.

Sascha


--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2010-01-06 07:03:17

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH v2] mmc: lower init clock frequency to 300kHz

On Sat 2010-01-02 10:11:10, Ben Nizette wrote:
>
> A good few months ago, commit
>
> commit 8dfd0374be84793360db7fff2e635d2cd3bbcb21
> Author: Sascha Hauer <[email protected]>
> Date: Thu Apr 9 08:32:02 2009 +0200
>
> MMC core: limit minimum initialization frequency to 400kHz
>
> broke a few setups with cards which don't quite adhere to the MMC spec - 400kHz is just too fast for them. In my testing, all of the cards which fail at 400kHz are OK by about 350Khz but this patch drops the floor to 300 to be on the safe side.
>
> Dropping the floor also means that the warning will trigger on some valid setups, albeit ones which won't run particularly crappy cards. This patch then slightly softens the language of said warning to make it clear it isn't always a problem.
>
> V1 of this patch dropped the floor all the way to 50kHz on the basis that it was only for a few 100 bytes so that very low speed shouldn't matter. After some discussion [1] the consensus was that 50 was too slow after all so this patch is a bit more sensible.
>

(please wrap).

> @@ -891,12 +891,12 @@ static void mmc_power_up(struct mmc_host *host)
> */
> mmc_delay(10);
>
> - if (host->f_min > 400000) {
> - pr_warning("%s: Minimum clock frequency too high for "
> + if (host->f_min > 300000) {
> + pr_warning("%s: Minimum clock frequency may be too high for "
> "identification mode\n", mmc_hostname(host));
> host->ios.clock = host->f_min;
> } else
> - host->ios.clock = 400000;
> + host->ios.clock = 300000;
>
> host->ios.power_mode = MMC_POWER_ON;
> mmc_set_ios(host);

Machine with minimum clock of 1MHz is clearly broken, yet you issue
"soft" warning.

What about:

if (f_min > 400k)
print existing warning
else if (f_min > 300k)
print warning 'if your card does not work, its broken, but
your host is unhelpful'
clock = f_min
if (clock < 3o0)
clock = 300

?
Pavel

--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2010-01-06 09:11:35

by Hein_Tibosch

[permalink] [raw]
Subject: Re: [PATCH v2] mmc: lower init clock frequency to 300kHz

On 6-1-2010 15:01, Pavel Machek wrote:
> Machine with minimum clock of 1MHz is clearly broken, yet you issue
> "soft" warning.
>
> What about:
>
> if (f_min > 400k)
> print existing warning
> else if (f_min > 300k)
> print warning 'if your card does not work, its broken, but
> your host is unhelpful'
> clock = f_min
> if (clock < 3o0)
> clock = 300
>
> ?
>
Later in this thread I mentioned that initialization at 300 Khz is
too fast for some platforms/cards (avr32 AP7000/main-stream cards).
They will report CRC-errors so the above won't work.

I have looked at the time it will take to exchange the initial data (about
85 bytes), using different busses and frequencies:

Intface: 8-bits 4-bits SPI
Bus-freq:
400000 (Hz) 0.213 0.425 1.700 (ms)
300000 0.283 0.567 2.267
200000 0.425 0.850 3.400
100000 0.850 1.700 6.800
50000 1.700 3.400 13.600
100 850 1700 6800

These are netto times, without the msleep's for power-up and without
overhead.

Looking at this table, I would use a fixed bottom of 100 Khz:

if (f_min > 400k)
print existing warning
clock = max (100k, host->f_min);

Regards, Hein






2010-08-27 20:44:32

by Chris Ball

[permalink] [raw]
Subject: Re: [PATCH v3] mmc: Make ID freq configurable

Hi,

This looks like the best of the min_freq patches I've seen, and is
implementing a suggestion of Pierre's. Should we take it?

- Chris.

On Tue, Jan 05, 2010 at 05:58:34AM +0800, Hein_Tibosch wrote:
>
> In my last mail the spaces in the patch were mistreated, sorry for that.
>
> Below a patch which tries mmc-initialization using several frequencies
> from an array 400, 300, 200 and 100.
>
>
> Signed-off-by: Hein Tibosch <[email protected]>
>
> ---
> diff -Nurp a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -891,12 +891,7 @@ static void mmc_power_up(struct mmc_host
> */
> mmc_delay(10);
>
> - if (host->f_min > 400000) {
> - pr_warning("%s: Minimum clock frequency too high for "
> - "identification mode\n", mmc_hostname(host));
> - host->ios.clock = host->f_min;
> - } else
> - host->ios.clock = 400000;
> + host->ios.clock = host->f_init;
>
> host->ios.power_mode = MMC_POWER_ON;
> mmc_set_ios(host);
> @@ -1041,6 +1036,8 @@ void mmc_rescan(struct work_struct *work
> container_of(work, struct mmc_host, detect.work);
> u32 ocr;
> int err;
> + int i;
> + unsigned freqs[] = { 400000, 300000, 200000, 100000 };
>
> mmc_bus_get(host);
>
> @@ -1070,46 +1067,55 @@ void mmc_rescan(struct work_struct *work
> if (host->ops->get_cd && host->ops->get_cd(host) == 0)
> goto out;
>
> - mmc_claim_host(host);
> + for (i = 0; i < ARRAY_SIZE(freqs); i++) {
> + mmc_claim_host(host);
>
> - mmc_power_up(host);
> - mmc_go_idle(host);
> + if (freqs[i] >= host->f_min)
> + host->f_init = freqs[i];
> + else if (i && freqs[i-1] <= host->f_min)
> + goto out;
> + else
> + host->f_init = host->f_min;
>
> - mmc_send_if_cond(host, host->ocr_avail);
> + printk ("mmc_rescan: trying %u Hz\n", host->f_init);
> + mmc_power_up(host);
> + mmc_go_idle(host);
>
> - /*
> - * First we search for SDIO...
> - */
> - err = mmc_send_io_op_cond(host, 0, &ocr);
> - if (!err) {
> - if (mmc_attach_sdio(host, ocr))
> - mmc_power_off(host);
> - goto out;
> - }
> + mmc_send_if_cond(host, host->ocr_avail);
>
> - /*
> - * ...then normal SD...
> - */
> - err = mmc_send_app_op_cond(host, 0, &ocr);
> - if (!err) {
> - if (mmc_attach_sd(host, ocr))
> - mmc_power_off(host);
> - goto out;
> - }
> + /*
> + * First we search for SDIO...
> + */
> + err = mmc_send_io_op_cond(host, 0, &ocr);
> + if (!err) {
> + if (mmc_attach_sdio(host, ocr))
> + mmc_power_off(host);
> + goto out;
> + }
>
> - /*
> - * ...and finally MMC.
> - */
> - err = mmc_send_op_cond(host, 0, &ocr);
> - if (!err) {
> - if (mmc_attach_mmc(host, ocr))
> - mmc_power_off(host);
> - goto out;
> - }
> + /*
> + * ...then normal SD...
> + */
> + err = mmc_send_app_op_cond(host, 0, &ocr);
> + if (!err) {
> + if (mmc_attach_sd(host, ocr))
> + mmc_power_off(host);
> + goto out;
> + }
>
> - mmc_release_host(host);
> - mmc_power_off(host);
> + /*
> + * ...and finally MMC.
> + */
> + err = mmc_send_op_cond(host, 0, &ocr);
> + if (!err) {
> + if (mmc_attach_mmc(host, ocr))
> + mmc_power_off(host);
> + goto out;
> + }
>
> + mmc_release_host(host);
> + mmc_power_off(host);
> + }
> out:
> if (host->caps & MMC_CAP_NEEDS_POLL)
> mmc_schedule_delayed_work(&host->detect, HZ);
> diff -Nurp a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -119,6 +119,7 @@ struct mmc_host {
> const struct mmc_host_ops *ops;
> unsigned int f_min;
> unsigned int f_max;
> + unsigned int f_init;
> u32 ocr_avail;
>
> #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
>
>
> --

--
Chris Ball <[email protected]> <http://printf.net/>
One Laptop Per Child

2010-08-28 01:17:35

by Hein_Tibosch

[permalink] [raw]
Subject: Re: [PATCH v3] mmc: Make ID freq configurable

On 28-8-2010 04:44, Chris Ball wrote:
> Hi,
>
> This looks like the best of the min_freq patches I've seen, and is
> implementing a suggestion of Pierre's. Should we take it?
>
> - Chris.
>
> On Tue, Jan 05, 2010 at 05:58:34AM +0800, Hein_Tibosch wrote:
>> Below a patch which tries mmc-initialization using several frequencies
>> from an array 400, 300, 200 and 100.
>>
>>
>> Signed-off-by: Hein Tibosch <[email protected]>
>> <cut>
Hi Chris,

Thanks. I can confirm that the above patch has been working properly for
7 months now, using various SD-cards.

Here it tries 3 frequencies, which takes 290 ms:

000 mmc_rescan: trying 400000 Hz
Waiting 1sec before mounting root device...
061 mci: F now 400000 (actual 397727)
usb 1-2: configuration #1 chosen from 1 choice
126 mmc_rescan: trying 300000 Hz
input: eGalax Inc. USB TouchController as /class/input/input1
193 mci: F now 300000 (actual 299145)
227 mmc_rescan: trying 200000 Hz
255 mci: F now 200000 (actual 200000)
290 mmc0: new SD card at address e624

In a meanwhile it is doing other things, so not much time is wasted.
But most importantly: it never failed to initialize a card.

Hein Tibosch