From: Jaehoon Chung <jh80.chung@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2] mmc: Split device init to decouple OCR-polling delay
Date: Fri, 30 Nov 2012 17:25:42 +0900 [thread overview]
Message-ID: <50B86D86.9060700@samsung.com> (raw)
In-Reply-To: <1354152073-26592-1-git-send-email-sjg@chromium.org>
Hi,
This concept is very good.
But I have one question. I think need to call mmc_init() one more, right?
how did you save the boot time(200ms)?
On 11/29/2012 10:21 AM, Simon Glass wrote:
> From: Che-Liang Chiou <clchiou@chromium.org>
>
> Most of time that MMC driver spends on initializing a device is polling
> OCR (operation conditions register). To decouple this polling loop,
> device init is split into two parts: The first part fires the OCR query
> command, and the second part polls the result. So the caller is now no
> longer bound to the OCR-polling delay; he may fire the query, go
> somewhere and then come back later for the result.
>
> To use this, call mmc_set_preinit() on any device which needs this.
>
> This can save significant amounts of time on boot (e.g. 200ms) by
> hiding the MMC init time behind other init.
snip..
> +int mmc_init(struct mmc *mmc)
> +{
> + int err = IN_PROGRESS;
> + unsigned start = get_timer(0);
> +
> + if (mmc->has_init)
> + return 0;
> + if (!mmc->init_in_progress)
> + err = mmc_start_init(mmc);
It need not to return? if err is IN_PROGRESS, next condition is immediately run.
Then i think we didn't save the time before adjust this patch.
> +
> + if (!err || err == IN_PROGRESS)
> + err = mmc_complete_init(mmc);
> + debug("%s: %d, time %lu\n", __func__, err, get_timer(start));
> return err;
> }
>
> @@ -1315,6 +1368,25 @@ int get_mmc_num(void)
> return cur_dev_num;
> }
>
> +void mmc_set_preinit(struct mmc *mmc, int preinit)
> +{
> + mmc->preinit = preinit;
> +}
> +
> +static void do_preinit(void)
> +{
> + struct mmc *m;
> + struct list_head *entry;
> +
> + list_for_each(entry, &mmc_devices) {
> + m = list_entry(entry, struct mmc, link);
> +
> + if (m->preinit)
> + mmc_start_init(m);
> + }
> +}
> +
> +
> int mmc_initialize(bd_t *bis)
> {
> INIT_LIST_HEAD (&mmc_devices);
> @@ -1325,5 +1397,6 @@ int mmc_initialize(bd_t *bis)
>
> print_mmc_devices(',');
>
> + do_preinit();
> return 0;
> }
> diff --git a/include/mmc.h b/include/mmc.h
> index a13e2bd..445d714 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -62,6 +62,7 @@
> #define UNUSABLE_ERR -17 /* Unusable Card */
> #define COMM_ERR -18 /* Communications Error */
> #define TIMEOUT -19
> +#define IN_PROGRESS -20 /* operation is in progress */
>
> #define MMC_CMD_GO_IDLE_STATE 0
> #define MMC_CMD_SEND_OP_COND 1
> @@ -260,6 +261,10 @@ struct mmc {
> int (*init)(struct mmc *mmc);
> int (*getcd)(struct mmc *mmc);
> uint b_max;
> + char op_cond_pending; /* 1 if we are waiting on an op_cond command */
> + char init_in_progress; /* 1 if we have done mmc_start_init() */
> + char preinit; /* start init as early as possible */
> + uint op_cond_response; /* the response byte from the last op_cond */
> };
>
> int mmc_register(struct mmc *mmc);
> @@ -276,6 +281,31 @@ int mmc_switch_part(int dev_num, unsigned int part_num);
> int mmc_getcd(struct mmc *mmc);
> void spl_mmc_load(void) __noreturn;
>
> +/**
> + * Start device initialization and return immediately; it does not block on
> + * polling OCR (operation condition register) status. Then you should call
> + * mmc_init, which would block on polling OCR status and complete the device
> + * initializatin.
> + *
> + * @param mmc Pointer to a MMC device struct
> + * @return 0 on success, IN_PROGRESS on waiting for OCR status, <0 on error.
> + */
> +int mmc_start_init(struct mmc *mmc);
> +
> +/**
> + * Set preinit flag of mmc device.
> + *
> + * This will cause the device to be pre-inited during mmc_initialize(),
> + * which may save boot time if the device is not accessed until later.
> + * Some eMMC devices take 200-300ms to init, but unfortunately they
> + * must be sent a series of commands to even get them to start preparing
> + * for operation.
> + *
> + * @param mmc Pointer to a MMC device struct
> + * @param preinit preinit flag value
> + */
> +void mmc_set_preinit(struct mmc *mmc, int preinit);
> +
> #ifdef CONFIG_GENERIC_MMC
> #define mmc_host_is_spi(mmc) ((mmc)->host_caps & MMC_MODE_SPI)
> struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
>
next prev parent reply other threads:[~2012-11-30 8:25 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-29 1:21 [U-Boot] [PATCH v2] mmc: Split device init to decouple OCR-polling delay Simon Glass
2012-11-29 15:20 ` Jae hoon Chung
2012-11-30 23:05 ` Simon Glass
2012-11-30 8:25 ` Jaehoon Chung [this message]
2012-11-30 23:13 ` Simon Glass
2012-12-15 17:18 ` Simon Glass
2012-12-17 2:12 ` Jaehoon Chung
2012-12-17 3:44 ` Simon Glass
2013-02-08 16:48 ` Simon Glass
2013-02-13 3:14 ` Jaehoon Chung
2013-03-16 20:35 ` Simon Glass
2013-04-03 18:49 ` Simon Glass
2013-04-29 5:02 ` Jaehoon Chung
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50B86D86.9060700@samsung.com \
--to=jh80.chung@samsung.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.