Commit 7a5b80297bc6cef0c10e5f57ac0450678dc7bc5e

Authored by Dirk Behme
Committed by Andy Fleming
1 parent ffdea5dab9

mmc: fsl_esdhc: Poll until card is not busy anymore

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.behme@de.bosch.com>
CC: Andy Fleming <afleming@freescale.com>
CC: Fabio Estevam <fabio.estevam@freescale.com>
CC: Stefano Babic <sbabic@denx.de>

Showing 2 changed files with 41 additions and 2 deletions Side-by-side Diff

drivers/mmc/fsl_esdhc.c
... ... @@ -307,18 +307,55 @@
307 307 #else
308 308 esdhc_write32(&regs->xfertyp, xfertyp);
309 309 #endif
  310 +
  311 + /* Mask all irqs */
  312 + esdhc_write32(&regs->irqsigen, 0);
  313 +
310 314 /* Wait for the command to complete */
311   - while (!(esdhc_read32(&regs->irqstat) & IRQSTAT_CC))
  315 + while (!(esdhc_read32(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
312 316 ;
313 317  
314 318 irqstat = esdhc_read32(&regs->irqstat);
315 319 esdhc_write32(&regs->irqstat, irqstat);
316 320  
  321 + /* Reset CMD and DATA portions on error */
  322 + if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
  323 + esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
  324 + SYSCTL_RSTC);
  325 + while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
  326 + ;
  327 +
  328 + if (data) {
  329 + esdhc_write32(&regs->sysctl,
  330 + esdhc_read32(&regs->sysctl) |
  331 + SYSCTL_RSTD);
  332 + while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
  333 + ;
  334 + }
  335 + }
  336 +
317 337 if (irqstat & CMD_ERR)
318 338 return COMM_ERR;
319 339  
320 340 if (irqstat & IRQSTAT_CTOE)
321 341 return TIMEOUT;
  342 +
  343 + /* Workaround for ESDHC errata ENGcm03648 */
  344 + if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
  345 + int timeout = 2500;
  346 +
  347 + /* Poll on DATA0 line for cmd with busy signal for 250 ms */
  348 + while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
  349 + PRSSTAT_DAT0)) {
  350 + udelay(100);
  351 + timeout--;
  352 + }
  353 +
  354 + if (timeout <= 0) {
  355 + printf("Timeout waiting for DAT0 to go high!\n");
  356 + return TIMEOUT;
  357 + }
  358 + }
322 359  
323 360 /* Copy the response to the response buffer */
324 361 if (cmd->resp_type & MMC_RSP_136) {
... ... @@ -34,12 +34,13 @@
34 34 #define SYSCTL_INITA 0x08000000
35 35 #define SYSCTL_TIMEOUT_MASK 0x000f0000
36 36 #define SYSCTL_CLOCK_MASK 0x0000fff0
37   -#define SYSCTL_RSTA 0x01000000
38 37 #define SYSCTL_CKEN 0x00000008
39 38 #define SYSCTL_PEREN 0x00000004
40 39 #define SYSCTL_HCKEN 0x00000002
41 40 #define SYSCTL_IPGEN 0x00000001
42 41 #define SYSCTL_RSTA 0x01000000
  42 +#define SYSCTL_RSTC 0x02000000
  43 +#define SYSCTL_RSTD 0x04000000
43 44  
44 45 #define IRQSTAT 0x0002e030
45 46 #define IRQSTAT_DMAE (0x10000000)
... ... @@ -85,6 +86,7 @@
85 86 #define IRQSTATEN_CC (0x00000001)
86 87  
87 88 #define PRSSTAT 0x0002e024
  89 +#define PRSSTAT_DAT0 (0x01000000)
88 90 #define PRSSTAT_CLSL (0x00800000)
89 91 #define PRSSTAT_WPSPL (0x00080000)
90 92 #define PRSSTAT_CDPL (0x00040000)