From patchwork Tue May 30 09:14:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Beno=C3=AEt_Th=C3=A9baudeau?= X-Patchwork-Id: 9754155 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A549B602BF for ; Tue, 30 May 2017 09:15:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9721C27569 for ; Tue, 30 May 2017 09:15:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8BE7427F10; Tue, 30 May 2017 09:15:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8498927569 for ; Tue, 30 May 2017 09:15:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751288AbdE3JOp (ORCPT ); Tue, 30 May 2017 05:14:45 -0400 Received: from authsmtp81.register.it ([195.110.122.166]:48773 "EHLO authsmtp.register.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750951AbdE3JOn (ORCPT ); Tue, 30 May 2017 05:14:43 -0400 Received: from rad-ubuntu.home ([90.105.184.123]) by paganini35 with id SZEL1v00U2g9efN01ZEfQ7; Tue, 30 May 2017 11:14:40 +0200 X-Rid: benoit@wsystem.com@90.105.184.123 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= To: linux-kernel@vger.kernel.org, linux-mmc@vger.kernel.org Cc: Ulf Hansson , Adrian Hunter , Fabio Estevam , Wolfram Sang , =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Subject: [PATCH v3 3/5] mmc: sdhci-esdhc-imx: Fix DAT line software reset Date: Tue, 30 May 2017 11:14:09 +0200 Message-Id: <1496135651-90007-3-git-send-email-benoit@wsystem.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1496135651-90007-1-git-send-email-benoit@wsystem.com> References: <1496135651-90007-1-git-send-email-benoit@wsystem.com> MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On i.MX25, the eSDHC DAT line software reset (SYSCTL.RSTD) unexpectedly clears at least the data transfer width (PROCTL.DTW), which then results in data CRC errors. This behavior is not documented, but it has actually been observed. Consequently, the DAT line software resets triggered by sdhci.c in case of errors caused unrecoverable errors. Fix this by making sure that the DAT line software reset does not alter the Host Control register. This behavior being undocumented, it may also be present on other i.MX SoCs, so apply this fix for the whole i.MX family. Signed-off-by: Benoît Thébaudeau Acked-by: Adrian Hunter Reviewed-by: Fabio Estevam --- Changes v1 -> v2: none. Changes v2 -> v3: none. --- drivers/mmc/host/sdhci-esdhc-imx.c | 59 ++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 4dbc5c0..790e7b2 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -579,7 +579,7 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); - u32 new_val; + u32 new_val = 0; u32 mask; switch (reg) { @@ -610,29 +610,46 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg) esdhc_clrset_le(host, mask, new_val, reg); return; + case SDHCI_SOFTWARE_RESET: + if (val & SDHCI_RESET_DATA) + new_val = readl(host->ioaddr + SDHCI_HOST_CONTROL); + break; } esdhc_clrset_le(host, 0xff, val, reg); - /* - * The esdhc has a design violation to SDHC spec which tells - * that software reset should not affect card detection circuit. - * But esdhc clears its SYSCTL register bits [0..2] during the - * software reset. This will stop those clocks that card detection - * circuit relies on. To work around it, we turn the clocks on back - * to keep card detection circuit functional. - */ - if ((reg == SDHCI_SOFTWARE_RESET) && (val & 1)) { - esdhc_clrset_le(host, 0x7, 0x7, ESDHC_SYSTEM_CONTROL); - /* - * The reset on usdhc fails to clear MIX_CTRL register. - * Do it manually here. - */ - if (esdhc_is_usdhc(imx_data)) { - /* the tuning bits should be kept during reset */ - new_val = readl(host->ioaddr + ESDHC_MIX_CTRL); - writel(new_val & ESDHC_MIX_CTRL_TUNING_MASK, - host->ioaddr + ESDHC_MIX_CTRL); - imx_data->is_ddr = 0; + if (reg == SDHCI_SOFTWARE_RESET) { + if (val & SDHCI_RESET_ALL) { + /* + * The esdhc has a design violation to SDHC spec which + * tells that software reset should not affect card + * detection circuit. But esdhc clears its SYSCTL + * register bits [0..2] during the software reset. This + * will stop those clocks that card detection circuit + * relies on. To work around it, we turn the clocks on + * back to keep card detection circuit functional. + */ + esdhc_clrset_le(host, 0x7, 0x7, ESDHC_SYSTEM_CONTROL); + /* + * The reset on usdhc fails to clear MIX_CTRL register. + * Do it manually here. + */ + if (esdhc_is_usdhc(imx_data)) { + /* + * the tuning bits should be kept during reset + */ + new_val = readl(host->ioaddr + ESDHC_MIX_CTRL); + writel(new_val & ESDHC_MIX_CTRL_TUNING_MASK, + host->ioaddr + ESDHC_MIX_CTRL); + imx_data->is_ddr = 0; + } + } else if (val & SDHCI_RESET_DATA) { + /* + * The eSDHC DAT line software reset clears at least the + * data transfer width on i.MX25, so make sure that the + * Host Control register is unaffected. + */ + esdhc_clrset_le(host, 0xff, new_val, + SDHCI_HOST_CONTROL); } } }