This patch imports parts of two patches from the Freescale U-Boot with the 
following
commit messages:

ENGR00156405 ESDHC: Add workaround for auto-clock gate errata ENGcm03648
http://git.freescale.com/git/cgit.cgi/imx/uboot-imx.git/commit/drivers/mmc/imx_esdhc.c?h=imx_v2009.08_12.01.01&id=e436525a70fe47623d346bc7d9f08f12ff8ad787
The errata, not applicable to USDHC, causes ESDHC to shut off clock to the card
when auto-clock gating is enabled for commands with busy signalling and no data
phase. The card might require the clock to exit the busy state, so the 
workaround
is to disable the auto-clock gate bits in SYSCTL register for such commands. The
workaround also entails polling on DAT0 bit in the PRSSTAT register to learn 
when
busy state is complete. Auto-clock gating is re-enabled at the end of busy 
state.

ENGR00156670-1 ESDHC/USDHC: Remove delay before each cmd and some bug fixes
http://git.freescale.com/git/cgit.cgi/imx/uboot-imx.git/commit/drivers/mmc/imx_esdhc.c?h=imx_v2009.08_12.01.01&id=a77c6fec8596891be96b2cdbc742c9824844b92a
Removed delay of 10 ms before each command. There should not be a need to have 
this
delay after the ENGR00156405 patch that polls until card is not busy anymore 
before
proceeding to next cmd.

This patch imports the polling part of both patches. The auto-clock gating code
don't apply for i.MX6 as implemented in these two patches. 

SYSCTL_RSTA was defined twice. Remove one definition.

Signed-off-by: Dirk Behme <dirk.be...@de.bosch.com>
CC: Andy Fleming <aflem...@freescale.com>
CC: Fabio Estevam <fabio.este...@freescale.com>
CC: Stefano Babic <sba...@denx.de>
---
Changes in v2:

* Drop the removal of the udelay(). It's not sure if the PowerPC would be
  ok with this removal.
* Drop touching the sysctl register. Reviewing the iMX6 spec shows that this
  was an NOP.

 drivers/mmc/fsl_esdhc.c |   39 ++++++++++++++++++++++++++++++++++++++-
 include/fsl_esdhc.h     |    4 +++-
 2 files changed, 41 insertions(+), 2 deletions(-)

Index: freescale-u-boot-imx.git/drivers/mmc/fsl_esdhc.c
===================================================================
--- freescale-u-boot-imx.git.orig/drivers/mmc/fsl_esdhc.c
+++ freescale-u-boot-imx.git/drivers/mmc/fsl_esdhc.c
@@ -307,19 +307,56 @@ esdhc_send_cmd(struct mmc *mmc, struct m
 #else
        esdhc_write32(&regs->xfertyp, xfertyp);
 #endif
+
+       /* Mask all irqs */
+       esdhc_write32(&regs->irqsigen, 0);
+
        /* Wait for the command to complete */
-       while (!(esdhc_read32(&regs->irqstat) & IRQSTAT_CC))
+       while (!(esdhc_read32(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
                ;
 
        irqstat = esdhc_read32(&regs->irqstat);
        esdhc_write32(&regs->irqstat, irqstat);
 
+       /* Reset CMD and DATA portions on error */
+       if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
+               esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
+                             SYSCTL_RSTC);
+               while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
+                       ;
+
+               if (data) {
+                       esdhc_write32(&regs->sysctl,
+                                     esdhc_read32(&regs->sysctl) |
+                                     SYSCTL_RSTD);
+                       while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
+                               ;
+               }
+       }
+
        if (irqstat & CMD_ERR)
                return COMM_ERR;
 
        if (irqstat & IRQSTAT_CTOE)
                return TIMEOUT;
 
+       /* Workaround for ESDHC errata ENGcm03648 */
+       if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
+               int timeout = 2500;
+
+               /* Poll on DATA0 line for cmd with busy signal for 250 ms */
+               while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
+                                       PRSSTAT_DAT0)) {
+                       udelay(100);
+                       timeout--;
+               }
+
+               if (timeout <= 0) {
+                       printf("Timeout waiting for DAT0 to go high!\n");
+                       return TIMEOUT;
+               }
+       }
+
        /* Copy the response to the response buffer */
        if (cmd->resp_type & MMC_RSP_136) {
                u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
Index: freescale-u-boot-imx.git/include/fsl_esdhc.h
===================================================================
--- freescale-u-boot-imx.git.orig/include/fsl_esdhc.h
+++ freescale-u-boot-imx.git/include/fsl_esdhc.h
@@ -34,12 +34,13 @@
 #define SYSCTL_INITA           0x08000000
 #define SYSCTL_TIMEOUT_MASK    0x000f0000
 #define SYSCTL_CLOCK_MASK      0x0000fff0
-#define SYSCTL_RSTA            0x01000000
 #define SYSCTL_CKEN            0x00000008
 #define SYSCTL_PEREN           0x00000004
 #define SYSCTL_HCKEN           0x00000002
 #define SYSCTL_IPGEN           0x00000001
 #define SYSCTL_RSTA            0x01000000
+#define SYSCTL_RSTC            0x02000000
+#define SYSCTL_RSTD            0x04000000
 
 #define IRQSTAT                        0x0002e030
 #define IRQSTAT_DMAE           (0x10000000)
@@ -85,6 +86,7 @@
 #define IRQSTATEN_CC           (0x00000001)
 
 #define PRSSTAT                        0x0002e024
+#define PRSSTAT_DAT0           (0x01000000)
 #define PRSSTAT_CLSL           (0x00800000)
 #define PRSSTAT_WPSPL          (0x00080000)
 #define PRSSTAT_CDPL           (0x00040000)
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to