summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/freescale/mx50_rdp/mx50_rdp.c15
-rw-r--r--drivers/mmc/imx_esdhc.c36
-rw-r--r--include/asm-arm/arch-mx50/mx50.h1
-rw-r--r--include/configs/mx50_arm2.h10
-rw-r--r--include/configs/mx50_arm2_ddr2.h10
-rw-r--r--include/configs/mx50_arm2_lpddr2.h10
-rw-r--r--include/configs/mx50_rd3.h10
-rw-r--r--include/configs/mx50_rdp.h10
-rw-r--r--include/configs/mx50_rdp_android.h10
-rw-r--r--include/fsl_esdhc.h4
10 files changed, 103 insertions, 13 deletions
diff --git a/board/freescale/mx50_rdp/mx50_rdp.c b/board/freescale/mx50_rdp/mx50_rdp.c
index 5bac73a..133ef6a 100644
--- a/board/freescale/mx50_rdp/mx50_rdp.c
+++ b/board/freescale/mx50_rdp/mx50_rdp.c
@@ -800,6 +800,21 @@ int detect_mmc_emmc_ddr_port(struct fsl_esdhc_cfg *cfg)
}
#endif
+/* The following function enables uSDHC instead of eSDHC
+ * on SD3 port for SDR mode since eSDHC timing on MX50
+ * is borderline for SDR mode. DDR mode will be disabled when this
+ * define is enabled since the uSDHC timing on MX50 is borderline
+ * for DDR mode. */
+#ifdef CONFIG_MX50_ENABLE_USDHC_SDR
+void enable_usdhc()
+{
+ /* Bring DIGCTL block out of reset and ungate clock */
+ writel(0xC0000000, DIGCTL_BASE_ADDR + 0x8);
+ /* Set bit 0 to select uSDHC */
+ writel(1, DIGCTL_BASE_ADDR + 0x4);
+}
+#endif
+
int esdhc_gpio_init(bd_t *bis)
{
s32 status = 0;
diff --git a/drivers/mmc/imx_esdhc.c b/drivers/mmc/imx_esdhc.c
index ced336a..f31176f 100644
--- a/drivers/mmc/imx_esdhc.c
+++ b/drivers/mmc/imx_esdhc.c
@@ -66,12 +66,15 @@ struct fsl_esdhc {
uint autoc12err;
uint hostcapblt;
uint wml;
- char reserved1[8];
+ uint mixctrl;
+ char reserved1[4];
uint fevt;
char reserved2[12];
uint dllctrl;
uint dllstatus;
- char reserved3[148];
+ char reserved3[88];
+ uint vendorspec;
+ char reserved4[56];
uint hostver;
};
@@ -206,17 +209,24 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
/* Send the command */
writel(cmd->cmdarg, &regs->cmdarg);
+ /* for uSDHC, write to mixer control register */
+ writel(xfertyp, &regs->mixctrl);
writel(xfertyp, &regs->xfertyp);
/* Mask all irqs */
writel(0, &regs->irqsigen);
/* Wait for the command to complete */
- while (!(readl(&regs->irqstat) & IRQSTAT_CC));
+ while (!(readl(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
+ ;
irqstat = readl(&regs->irqstat);
writel(irqstat, &regs->irqstat);
+ /* Reset CMD portion on error */
+ if (irqstat & (CMD_ERR | IRQSTAT_CTOE))
+ writel(readl(&regs->sysctl) | SYSCTL_RSTC, &regs->sysctl);
+
if (irqstat & CMD_ERR)
return COMM_ERR;
@@ -281,9 +291,12 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
while (!(readl(&regs->irqstat) & IRQSTAT_TC)) ;
}
- if (readl(&regs->irqstat) & 0xFFFF0000)
+ /* Reset CMD and DATA portions of the controller on error */
+ if (readl(&regs->irqstat) & 0xFFFF0000) {
+ writel(readl(&regs->sysctl) | SYSCTL_RSTC | SYSCTL_RSTD,
+ &regs->sysctl);
return COMM_ERR;
-
+ }
writel(-1, &regs->irqstat);
return 0;
@@ -479,6 +492,11 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
mmc->set_ios = esdhc_set_ios;
mmc->init = esdhc_init;
+/* Enable uSDHC if the config is defined (only for i.MX50 in SDR mode) */
+#ifdef CONFIG_MX50_ENABLE_USDHC_SDR
+ enable_usdhc();
+#endif
+
caps = readl(&regs->hostcapblt);
if (caps & ESDHC_HOSTCAPBLT_VS30)
mmc->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
@@ -490,6 +508,10 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
if (caps & ESDHC_HOSTCAPBLT_HSS)
mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+/* Do not advertise DDR capability for uSDHC on MX50 since
+ * it is to be used in SDR mode only. Use eSDHC for DDR mode.
+ */
+#ifndef CONFIG_MX50_ENABLE_USDHC_SDR
if (((readl(&regs->hostver) & ESDHC_HOSTVER_VVN_MASK)
>> ESDHC_HOSTVER_VVN_SHIFT) >= ESDHC_HOSTVER_DDR_SUPPORT)
mmc->host_caps |= EMMC_MODE_4BIT_DDR;
@@ -499,8 +521,10 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
mmc->host_caps |= EMMC_MODE_4BIT_DDR;
#endif
+#endif /* #ifndef CONFIG_MX50_ENABLE_USDHC_SDR */
+
mmc->f_min = 400000;
- mmc->f_max = MIN(mxc_get_clock(MXC_ESDHC_CLK), 50000000);
+ mmc->f_max = MIN(mxc_get_clock(MXC_ESDHC_CLK), 52000000);
mmc_register(mmc);
diff --git a/include/asm-arm/arch-mx50/mx50.h b/include/asm-arm/arch-mx50/mx50.h
index 9c905e5..c004951 100644
--- a/include/asm-arm/arch-mx50/mx50.h
+++ b/include/asm-arm/arch-mx50/mx50.h
@@ -44,6 +44,7 @@
#define CORTEX_DBG_BASE_ADDR (DEBUG_BASE_ADDR + 0x00008000)
#define ABPHDMA_BASE_ADDR (DEBUG_BASE_ADDR + 0x01000000)
#define OCOTP_CTRL_BASE_ADDR (DEBUG_BASE_ADDR + 0x01002000)
+#define DIGCTL_BASE_ADDR (DEBUG_BASE_ADDR + 0x01004000)
#define GPMI_BASE_ADDR (DEBUG_BASE_ADDR + 0x01006000)
#define BCH_BASE_ADDR (DEBUG_BASE_ADDR + 0x01008000)
#define EPDC_BASE_ADDR (DEBUG_BASE_ADDR + 0x01010000)
diff --git a/include/configs/mx50_arm2.h b/include/configs/mx50_arm2.h
index d6a56e0..d0266cc 100644
--- a/include/configs/mx50_arm2.h
+++ b/include/configs/mx50_arm2.h
@@ -251,7 +251,15 @@
#define CONFIG_EMMC_DDR_MODE
/* Indicate to esdhc driver which ports support 8-bit data */
- #define CONFIG_MMC_8BIT_PORTS 0x6 /* ports 1 and 2 */
+ #define CONFIG_MMC_8BIT_PORTS 0x6 /* SD2 and SD3 */
+
+ /* Uncomment the following define to enable uSDHC instead
+ * of eSDHC on SD3 port for SDR mode since eSDHC timing on MX50
+ * is borderline for SDR mode. DDR mode will be disabled when this
+ * define is enabled since the uSDHC timing on MX50 is borderline
+ * for DDR mode. */
+
+ /*#define CONFIG_MX50_ENABLE_USDHC_SDR 1*/
#endif
/*
diff --git a/include/configs/mx50_arm2_ddr2.h b/include/configs/mx50_arm2_ddr2.h
index e2eac01..c5e8bce 100644
--- a/include/configs/mx50_arm2_ddr2.h
+++ b/include/configs/mx50_arm2_ddr2.h
@@ -242,7 +242,15 @@
#define CONFIG_EMMC_DDR_MODE
/* Indicate to esdhc driver which ports support 8-bit data */
- #define CONFIG_MMC_8BIT_PORTS 0x6 /* ports 1 & 2 */
+ #define CONFIG_MMC_8BIT_PORTS 0x6 /* SD2 and SD3 */
+
+ /* Uncomment the following define to enable uSDHC instead
+ * of eSDHC on SD3 port for SDR mode since eSDHC timing on MX50
+ * is borderline for SDR mode. DDR mode will be disabled when this
+ * define is enabled since the uSDHC timing on MX50 is borderline
+ * for DDR mode. */
+
+ /*#define CONFIG_MX50_ENABLE_USDHC_SDR 1*/
#endif
diff --git a/include/configs/mx50_arm2_lpddr2.h b/include/configs/mx50_arm2_lpddr2.h
index d7e3aea..d1751df 100644
--- a/include/configs/mx50_arm2_lpddr2.h
+++ b/include/configs/mx50_arm2_lpddr2.h
@@ -243,7 +243,15 @@
#define CONFIG_EMMC_DDR_MODE
/* Indicate to esdhc driver which ports support 8-bit data */
- #define CONFIG_MMC_8BIT_PORTS 0x6 /* ports 1 and 2 */
+ #define CONFIG_MMC_8BIT_PORTS 0x6 /* SD2 and SD3 */
+
+ /* Uncomment the following define to enable uSDHC instead
+ * of eSDHC on SD3 port for SDR mode since eSDHC timing on MX50
+ * is borderline for SDR mode. DDR mode will be disabled when this
+ * define is enabled since the uSDHC timing on MX50 is borderline
+ * for DDR mode. */
+
+ /*#define CONFIG_MX50_ENABLE_USDHC_SDR 1*/
#endif
/*
diff --git a/include/configs/mx50_rd3.h b/include/configs/mx50_rd3.h
index 98d299d..58229a1 100644
--- a/include/configs/mx50_rd3.h
+++ b/include/configs/mx50_rd3.h
@@ -220,7 +220,15 @@
#define CONFIG_EMMC_DDR_MODE
/* Indicate to esdhc driver which ports support 8-bit data */
- #define CONFIG_MMC_8BIT_PORTS 0x6 /* ports 1 and 2 */
+ #define CONFIG_MMC_8BIT_PORTS 0x6 /* SD2 and SD3 */
+
+ /* Uncomment the following define to enable uSDHC instead
+ * of eSDHC on SD3 port for SDR mode since eSDHC timing on MX50
+ * is borderline for SDR mode. DDR mode will be disabled when this
+ * define is enabled since the uSDHC timing on MX50 is borderline
+ * for DDR mode. */
+
+ /*#define CONFIG_MX50_ENABLE_USDHC_SDR 1*/
#endif
/*
diff --git a/include/configs/mx50_rdp.h b/include/configs/mx50_rdp.h
index 8fb1189..fff16a9 100644
--- a/include/configs/mx50_rdp.h
+++ b/include/configs/mx50_rdp.h
@@ -220,7 +220,15 @@
#define CONFIG_EMMC_DDR_MODE
/* Indicate to esdhc driver which ports support 8-bit data */
- #define CONFIG_MMC_8BIT_PORTS 0x6 /* ports 1 and 2 */
+ #define CONFIG_MMC_8BIT_PORTS 0x6 /* SD2 and SD3 */
+
+ /* Uncomment the following define to enable uSDHC instead
+ * of eSDHC on SD3 port for SDR mode since eSDHC timing on MX50
+ * is borderline for SDR mode. DDR mode will be disabled when this
+ * define is enabled since the uSDHC timing on MX50 is borderline
+ * for DDR mode. */
+
+ /*#define CONFIG_MX50_ENABLE_USDHC_SDR 1*/
#endif
/*
diff --git a/include/configs/mx50_rdp_android.h b/include/configs/mx50_rdp_android.h
index 0b6eb8d..f3675dd 100644
--- a/include/configs/mx50_rdp_android.h
+++ b/include/configs/mx50_rdp_android.h
@@ -220,7 +220,15 @@
#define CONFIG_EMMC_DDR_MODE
/* Indicate to esdhc driver which ports support 8-bit data */
- #define CONFIG_MMC_8BIT_PORTS 0x2 /* ports 1 and 2 */
+ #define CONFIG_MMC_8BIT_PORTS 0x6 /* SD2 and SD3 */
+
+ /* Uncomment the following define to enable uSDHC instead
+ * of eSDHC on SD3 port for SDR mode since eSDHC timing on MX50
+ * is borderline for SDR mode. DDR mode will be disabled when this
+ * define is enabled since the uSDHC timing on MX50 is borderline
+ * for DDR mode. */
+
+ /*#define CONFIG_MX50_ENABLE_USDHC_SDR 1*/
#endif
/*
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index e32d7d2..1787407 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -2,7 +2,7 @@
* FSL SD/MMC Defines
*-------------------------------------------------------------------
*
- * Copyright (C) 2007-2008, 2010 Freescale Semiconductor, Inc.
+ * Copyright (C) 2007-2008, 2010-2011 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -34,6 +34,8 @@
#define SYSCTL_TIMEOUT_MASK 0x000f0000
#define SYSCTL_CLOCK_MASK 0x0000fff0
#define SYSCTL_RSTA 0x01000000
+#define SYSCTL_RSTC 0x02000000
+#define SYSCTL_RSTD 0x04000000
#define SYSCTL_SDCLKEN 0x00000008
#define SYSCTL_PEREN 0x00000004
#define SYSCTL_HCKEN 0x00000002