diff mbox

[U-Boot,v2,1/4] mmc: fsl_esdhc: Add CMD11 support to switch to 1.8V

Message ID 1424176966-24749-1-git-send-email-otavio@ossystems.com.br
State Accepted
Delegated to: Stefano Babic
Headers show

Commit Message

Otavio Salvador Feb. 17, 2015, 12:42 p.m. UTC
This adds support to switch to 1.8V in case CMD11 succeeds.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---

Changes in v2:
- Fixed split string (Marek)

 drivers/mmc/fsl_esdhc.c | 29 ++++++++++++++++++++++-------
 include/fsl_esdhc.h     |  2 ++
 include/mmc.h           |  1 +
 3 files changed, 25 insertions(+), 7 deletions(-)

Comments

Marek Vasut Feb. 17, 2015, 7:41 p.m. UTC | #1
On Tuesday, February 17, 2015 at 01:42:43 PM, Otavio Salvador wrote:
> This adds support to switch to 1.8V in case CMD11 succeeds.
> 
> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
> ---
> 
> Changes in v2:
> - Fixed split string (Marek)
> 
>  drivers/mmc/fsl_esdhc.c | 29 ++++++++++++++++++++++-------
>  include/fsl_esdhc.h     |  2 ++
>  include/mmc.h           |  1 +
>  3 files changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
> index c55eb28..6a3e147 100644
> --- a/drivers/mmc/fsl_esdhc.c
> +++ b/drivers/mmc/fsl_esdhc.c
> @@ -54,19 +54,21 @@ struct fsl_esdhc {
>  	uint    fevt;		/* Force event register */
>  	uint    admaes;		/* ADMA error status register */
>  	uint    adsaddr;	/* ADMA system address register */
> -	char    reserved2[160];	/* reserved */
> +	char    reserved2[100];	/* reserved */
> +	uint    vendorspec;	/* Vendor Specific register */
> +	char    reserved3[59];	/* reserved */
>  	uint    hostver;	/* Host controller version register */
> -	char    reserved3[4];	/* reserved */
> -	uint    dmaerraddr;	/* DMA error address register */
>  	char    reserved4[4];	/* reserved */
> -	uint    dmaerrattr;	/* DMA error attribute register */
> +	uint    dmaerraddr;	/* DMA error address register */
>  	char    reserved5[4];	/* reserved */
> +	uint    dmaerrattr;	/* DMA error attribute register */
> +	char    reserved6[4];	/* reserved */
>  	uint    hostcapblt2;	/* Host controller capabilities register 2 */
> -	char    reserved6[8];	/* reserved */
> +	char    reserved7[8];	/* reserved */
>  	uint    tcr;		/* Tuning control register */
> -	char    reserved7[28];	/* reserved */
> +	char    reserved8[28];	/* reserved */
>  	uint    sddirctl;	/* SD direction control register */
> -	char    reserved8[712];	/* reserved */
> +	char    reserved9[712];	/* reserved */
>  	uint    scr;		/* eSDHC control register */
>  };
> 
> @@ -341,6 +343,15 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> struct mmc_data *data) goto out;
>  	}
> 
> +	/* Switch voltage to 1.8V if CMD11 succeeded */
> +	if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V) {
> +		esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);
> +
> +		printf("Run CMD11 1.8V switch\n");
> +		/* Sleep for 5 ms - max time for card to switch to 1.8V */
> +		udelay(5000);
> +	}
> +
>  	/* Workaround for ESDHC errata ENGcm03648 */
>  	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
>  		int timeout = 2500;
> @@ -413,6 +424,10 @@ out:
>  			while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
>  				;

This endless loop could use fixing ... anyone ?

>  		}
> +
> +		/* If this was CMD11, then notify that power cycle is needed */
> +		if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V)
> +			printf("CMD11 to switch to 1.8V mode failed, card 
requires power
> cycle.\n"); }
> 
>  	esdhc_write32(&regs->irqstat, -1);

Reviewed-by: Marek Vasut <marex@denx.de>
Stefano Babic Feb. 23, 2015, 8:19 a.m. UTC | #2
On 17/02/2015 13:42, Otavio Salvador wrote:
> This adds support to switch to 1.8V in case CMD11 succeeds.
> 
> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
> ---


Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic
diff mbox

Patch

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index c55eb28..6a3e147 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -54,19 +54,21 @@  struct fsl_esdhc {
 	uint    fevt;		/* Force event register */
 	uint    admaes;		/* ADMA error status register */
 	uint    adsaddr;	/* ADMA system address register */
-	char    reserved2[160];	/* reserved */
+	char    reserved2[100];	/* reserved */
+	uint    vendorspec;	/* Vendor Specific register */
+	char    reserved3[59];	/* reserved */
 	uint    hostver;	/* Host controller version register */
-	char    reserved3[4];	/* reserved */
-	uint    dmaerraddr;	/* DMA error address register */
 	char    reserved4[4];	/* reserved */
-	uint    dmaerrattr;	/* DMA error attribute register */
+	uint    dmaerraddr;	/* DMA error address register */
 	char    reserved5[4];	/* reserved */
+	uint    dmaerrattr;	/* DMA error attribute register */
+	char    reserved6[4];	/* reserved */
 	uint    hostcapblt2;	/* Host controller capabilities register 2 */
-	char    reserved6[8];	/* reserved */
+	char    reserved7[8];	/* reserved */
 	uint    tcr;		/* Tuning control register */
-	char    reserved7[28];	/* reserved */
+	char    reserved8[28];	/* reserved */
 	uint    sddirctl;	/* SD direction control register */
-	char    reserved8[712];	/* reserved */
+	char    reserved9[712];	/* reserved */
 	uint    scr;		/* eSDHC control register */
 };
 
@@ -341,6 +343,15 @@  esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 		goto out;
 	}
 
+	/* Switch voltage to 1.8V if CMD11 succeeded */
+	if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V) {
+		esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);
+
+		printf("Run CMD11 1.8V switch\n");
+		/* Sleep for 5 ms - max time for card to switch to 1.8V */
+		udelay(5000);
+	}
+
 	/* Workaround for ESDHC errata ENGcm03648 */
 	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
 		int timeout = 2500;
@@ -413,6 +424,10 @@  out:
 			while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
 				;
 		}
+
+		/* If this was CMD11, then notify that power cycle is needed */
+		if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V)
+			printf("CMD11 to switch to 1.8V mode failed, card requires power cycle.\n");
 	}
 
 	esdhc_write32(&regs->irqstat, -1);
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index c1b6648..e3d6581 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -154,6 +154,8 @@ 
 #define ESDHC_HOSTCAPBLT_DMAS	0x00400000
 #define ESDHC_HOSTCAPBLT_HSS	0x00200000
 
+#define ESDHC_VENDORSPEC_VSELECT 0x00000002 /* Use 1.8V */
+
 struct fsl_esdhc_cfg {
 	u32	esdhc_base;
 	u32	sdhc_clk;
diff --git a/include/mmc.h b/include/mmc.h
index 56d97bb..e4b071e 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -88,6 +88,7 @@ 
 #define SD_CMD_SEND_RELATIVE_ADDR	3
 #define SD_CMD_SWITCH_FUNC		6
 #define SD_CMD_SEND_IF_COND		8
+#define SD_CMD_SWITCH_UHS18V		11
 
 #define SD_CMD_APP_SET_BUS_WIDTH	6
 #define SD_CMD_ERASE_WR_BLK_START	32