Merge branch 'master' of git://git.denx.de/u-boot-nand-flash
[oweals/u-boot.git] / drivers / mmc / fsl_esdhc.c
index bd8c539a571c7201af880c4e7bc14267b1f0a6c5..7b146a360444b1a3f524aaf43c0be0eac76eb0aa 100644 (file)
 DECLARE_GLOBAL_DATA_PTR;
 
 struct fsl_esdhc {
-       uint    dsaddr;
-       uint    blkattr;
-       uint    cmdarg;
-       uint    xfertyp;
-       uint    cmdrsp0;
-       uint    cmdrsp1;
-       uint    cmdrsp2;
-       uint    cmdrsp3;
-       uint    datport;
-       uint    prsstat;
-       uint    proctl;
-       uint    sysctl;
-       uint    irqstat;
-       uint    irqstaten;
-       uint    irqsigen;
-       uint    autoc12err;
-       uint    hostcapblt;
-       uint    wml;
-       uint    mixctrl;
-       char    reserved1[4];
-       uint    fevt;
-       uint    admaes;
-       uint    adsaddr;
-       char    reserved2[160];
-       uint    hostver;
-       char    reserved3[4];
-       uint    dmaerraddr;
-       char    reserved4[4];
-       uint    dmaerrattr;
-       char    reserved5[4];
-       uint    hostcapblt2;
-       char    reserved6[8];
-       uint    tcr;
-       char    reserved7[28];
-       uint    sddirctl;
-       char    reserved8[712];
-       uint    scr;
+       uint    dsaddr;         /* SDMA system address register */
+       uint    blkattr;        /* Block attributes register */
+       uint    cmdarg;         /* Command argument register */
+       uint    xfertyp;        /* Transfer type register */
+       uint    cmdrsp0;        /* Command response 0 register */
+       uint    cmdrsp1;        /* Command response 1 register */
+       uint    cmdrsp2;        /* Command response 2 register */
+       uint    cmdrsp3;        /* Command response 3 register */
+       uint    datport;        /* Buffer data port register */
+       uint    prsstat;        /* Present state register */
+       uint    proctl;         /* Protocol control register */
+       uint    sysctl;         /* System Control Register */
+       uint    irqstat;        /* Interrupt status register */
+       uint    irqstaten;      /* Interrupt status enable register */
+       uint    irqsigen;       /* Interrupt signal enable register */
+       uint    autoc12err;     /* Auto CMD error status register */
+       uint    hostcapblt;     /* Host controller capabilities register */
+       uint    wml;            /* Watermark level register */
+       uint    mixctrl;        /* For USDHC */
+       char    reserved1[4];   /* reserved */
+       uint    fevt;           /* Force event register */
+       uint    admaes;         /* ADMA error status register */
+       uint    adsaddr;        /* ADMA system address register */
+       char    reserved2[160]; /* 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 */
+       char    reserved5[4];   /* reserved */
+       uint    hostcapblt2;    /* Host controller capabilities register 2 */
+       char    reserved6[8];   /* reserved */
+       uint    tcr;            /* Tuning control register */
+       char    reserved7[28];  /* reserved */
+       uint    sddirctl;       /* SD direction control register */
+       char    reserved8[712]; /* reserved */
+       uint    scr;            /* eSDHC control register */
 };
 
 /* Return the XFERTYP flags for a given command and data packet */
@@ -500,6 +500,10 @@ static int esdhc_getcd(struct mmc *mmc)
        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
        int timeout = 1000;
 
+#ifdef CONFIG_ESDHC_DETECT_QUIRK
+       if (CONFIG_ESDHC_DETECT_QUIRK)
+               return 1;
+#endif
        while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) && --timeout)
                udelay(1000);
 
@@ -533,6 +537,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
        if (!mmc)
                return -ENOMEM;
 
+       memset(mmc, 0, sizeof(struct mmc));
        sprintf(mmc->name, "FSL_SDHC");
        regs = (struct fsl_esdhc *)cfg->esdhc_base;
 
@@ -556,6 +561,12 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
        caps = caps & ~(ESDHC_HOSTCAPBLT_SRS |
                        ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30);
 #endif
+
+/* T4240 host controller capabilities register should have VS33 bit */
+#ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33
+       caps = caps | ESDHC_HOSTCAPBLT_VS33;
+#endif
+
        if (caps & ESDHC_HOSTCAPBLT_VS18)
                voltage_caps |= MMC_VDD_165_195;
        if (caps & ESDHC_HOSTCAPBLT_VS30)
@@ -585,6 +596,11 @@ 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;
 
+#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK
+       if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK)
+               mmc->host_caps &= ~MMC_MODE_8BIT;
+#endif
+
        mmc->f_min = 400000;
        mmc->f_max = MIN(gd->arch.sdhc_clk, 52000000);