diff options
| author | Che-Liang Chiou <clchiou@chromium.org> | 2012-11-28 15:21:13 +0000 | 
|---|---|---|
| committer | Andy Fleming <afleming@freescale.com> | 2013-05-06 16:12:38 -0500 | 
| commit | e95504497ecac46907204b0ee3460b708a2981ac (patch) | |
| tree | c59e230a6096b5883c83d3399717a3408f601355 /include | |
| parent | 5ed6f447af60aabd2669d913f673793c1ce48f47 (diff) | |
| download | olio-uboot-2014.01-e95504497ecac46907204b0ee3460b708a2981ac.tar.xz olio-uboot-2014.01-e95504497ecac46907204b0ee3460b708a2981ac.zip | |
mmc: Split device init to decouple OCR-polling delay
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.
Signed-off-by: Che-Liang Chiou <clchiou@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/mmc.h | 30 | 
1 files changed, 30 insertions, 0 deletions
| diff --git a/include/mmc.h b/include/mmc.h index 8bbc6b6eb..566db59ac 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -68,6 +68,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 @@ -270,6 +271,10 @@ struct mmc {  	int (*getcd)(struct mmc *mmc);  	int (*getwp)(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); @@ -287,6 +292,31 @@ int mmc_getcd(struct mmc *mmc);  int mmc_getwp(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); |