diff options
author | Haijun Zhang <Haijun.Zhang@freescale.com> | 2013-10-23 03:29:58 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2013-12-18 19:18:02 (GMT) |
commit | f5cc56e30551b723ffc6f316161eda8cc555dfa5 (patch) | |
tree | 098bc577331d62b57af72815b47b928c2a856b6a /drivers/mmc/host | |
parent | 5709059c4e110944712dc1f3d66a203a924c151a (diff) | |
download | linux-fsl-qoriq-f5cc56e30551b723ffc6f316161eda8cc555dfa5.tar.xz |
esdhc: Add new models to ERRATA A-004388
A-004388: eSDHC DMA might not stop if error occurs on system transaction
New models as 5040/5021 were added to this errata, and some tiny change
was applied into the workaround.
Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
Change-Id: Id2e618b3dc69856e8c23a3ce46dc18bb2c07fded
Reviewed-on: http://git.am.freescale.net:8181/5924
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Xiaobo Xie <X.Xie@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r-- | drivers/mmc/host/sdhci-of-esdhc.c | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index c8ecca9..b82a4e6 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -228,41 +228,45 @@ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask) * Check for A-004388: eSDHC DMA might not stop if error * occurs on system transaction * Impact list: - * T4240-4160-R1.0 B4860-4420-R1.0 P1010-1014-R1.0 + * T4240-4160-R1.0 B4860-4420-R1.0-R2.0 P1010-1014-R1.0 * P3041-R1.0-R2.0-R1.1 P2041-2040-R1.0-R1.1-R2.0 - * P5040-5021-R2.0 + * P5020-5010-R2.0-R1.0 P5040-5021-R2.0-R2.1 */ if (!(((SVR_SOC_VER(svr) == SVR_T4240) && (SVR_REV(svr) == 0x10)) || ((SVR_SOC_VER(svr) == SVR_T4160) && (SVR_REV(svr) == 0x10)) || ((SVR_SOC_VER(svr) == SVR_B4420) && (SVR_REV(svr) == 0x10)) || + ((SVR_SOC_VER(svr) == SVR_B4420) && (SVR_REV(svr) == 0x20)) || ((SVR_SOC_VER(svr) == SVR_B4860) && (SVR_REV(svr) == 0x10)) || + ((SVR_SOC_VER(svr) == SVR_B4860) && (SVR_REV(svr) == 0x20)) || ((SVR_SOC_VER(svr) == SVR_P1010) && (SVR_REV(svr) == 0x10)) || ((SVR_SOC_VER(svr) == SVR_P1014) && (SVR_REV(svr) == 0x10)) || ((SVR_SOC_VER(svr) == SVR_P3041) && (SVR_REV(svr) <= 0x20)) || ((SVR_SOC_VER(svr) == SVR_P2041) && (SVR_REV(svr) <= 0x20)) || ((SVR_SOC_VER(svr) == SVR_P2040) && (SVR_REV(svr) <= 0x20)) || - ((SVR_SOC_VER(svr) == SVR_P5021) && (SVR_REV(svr) == 0x20)) || - ((SVR_SOC_VER(svr) == SVR_P5040) && (SVR_REV(svr) == 0x20)))) + ((SVR_SOC_VER(svr) == SVR_P5020) && (SVR_REV(svr) <= 0x20)) || + ((SVR_SOC_VER(svr) == SVR_P5010) && (SVR_REV(svr) <= 0x20)) || + ((SVR_SOC_VER(svr) == SVR_P5021) && (SVR_REV(svr) <= 0x21)) || + ((SVR_SOC_VER(svr) == SVR_P5040) && (SVR_REV(svr) <= 0x21)))) return; + sdhci_reset(host, SDHCI_RESET_DATA); + if (host->flags & SDHCI_USE_ADMA) { u32 mod, i, offset; u8 *desc; dma_addr_t addr; struct scatterlist *sg; + __le32 *dataddr; + __le32 *cmdlen; + /* + * If block count was enabled, in case read transfer there + * is no data was corrupted + */ mod = esdhc_readl(host, SDHCI_TRANSFER_MODE); - if (mod & SDHCI_TRNS_BLK_CNT_EN) { - /* In case read transfer there is no data - * was corrupted - */ - if (host->data->flags & MMC_DATA_READ) - return; + if ((mod & SDHCI_TRNS_BLK_CNT_EN) && + (host->data->flags & MMC_DATA_READ)) host->data->error = 0; - sdhci_reset(host, SDHCI_RESET_DATA); - } - - sdhci_reset(host, SDHCI_RESET_DATA); BUG_ON(!host->data); desc = host->adma_desc; @@ -281,30 +285,18 @@ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask) desc += 8; WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4); - if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) { - desc -= 8; - desc[0] |= 0x2; /* end */ - } else { - __le32 *dataddr = (__le32 __force *)(desc + 4); - __le16 *cmdlen = (__le16 __force *)desc; - - cmdlen[0] = cpu_to_le16(0x3); - cmdlen[1] = cpu_to_le16(0); + dataddr = (__le32 __force *)(desc + 4); + cmdlen = (__le32 __force *)desc; - dataddr[0] = cpu_to_le32(0); - } - - return; + cmdlen[0] = cpu_to_le32(0); + dataddr[0] = cpu_to_le32(0); } - if ((host->flags & SDHCI_USE_SDMA)) { - if (host->data->flags & MMC_DATA_READ) - return; - + if ((host->flags & SDHCI_USE_SDMA) && + (host->data->flags & MMC_DATA_READ)) host->data->error = 0; - sdhci_reset(host, SDHCI_RESET_DATA); - return; - } + + return; } static int esdhc_of_enable_dma(struct sdhci_host *host) |