From patchwork Thu Mar 8 12:36:38 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dirk Behme X-Patchwork-Id: 145516 X-Patchwork-Delegate: afleming@freescale.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 47957B6F9F for ; Thu, 8 Mar 2012 23:36:59 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E37AC2812D; Thu, 8 Mar 2012 13:36:57 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id G51Dc68d+RlL; Thu, 8 Mar 2012 13:36:57 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 40C3228122; Thu, 8 Mar 2012 13:36:56 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 6C91728122 for ; Thu, 8 Mar 2012 13:36:54 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9+eP1D8sUTWj for ; Thu, 8 Mar 2012 13:36:54 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from smtp2-v.fe.bosch.de (smtp2-v.fe.bosch.de [139.15.237.6]) by theia.denx.de (Postfix) with ESMTPS id D97E128121 for ; Thu, 8 Mar 2012 13:36:53 +0100 (CET) Received: from vsmta13.fe.internet.bosch.com (unknown [10.4.98.30]) by imta24.fe.bosch.de (Postfix) with ESMTP id 13217B3B87AD for ; Thu, 8 Mar 2012 13:36:23 +0100 (CET) Received: from localhost (vsgw3.fe.internet.bosch.com [10.4.98.16]) by vsmta13.fe.internet.bosch.com (Postfix) with SMTP id 6DA613840223 for ; Thu, 8 Mar 2012 13:36:53 +0100 (CET) Received: from SI-HUB1001.de.bosch.com (10.4.103.108) by fe-hub05.de.bosch.com (10.3.153.64) with Microsoft SMTP Server (TLS) id 8.3.213.0; Thu, 8 Mar 2012 13:36:49 +0100 Received: from hi-z5661.hi.de.bosch.com (10.34.217.179) by SI-HUB1001.de.bosch.com (10.4.103.108) with Microsoft SMTP Server id 14.1.355.2; Thu, 8 Mar 2012 13:36:49 +0100 Received: from localhost.localdomain (localhost [127.0.0.1]) by hi-z5661.hi.de.bosch.com (Postfix) with ESMTP id D76C64303A; Thu, 8 Mar 2012 13:36:48 +0100 (CET) From: Dirk Behme To: Date: Thu, 8 Mar 2012 13:36:38 +0100 Message-ID: <1331210198-11818-1-git-send-email-dirk.behme@de.bosch.com> X-Mailer: git-send-email 1.7.0.4 MIME-Version: 1.0 Cc: Fabio Estevam , Dirk Behme , Andy Fleming Subject: [U-Boot] [PATCH] mmc: fsl_esdhc: Add workaround for auto-clock gate errata ENGcm03648 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This patch imports three 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. ENGR00161852: remove u-boot build warnings for mx6q 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=97efee177f82b082db9d2019ed641c5b99b3f54b Remove u-boot build warnings for mx6q. SYSCTL_RSTA was defined twice. Remove one definition. Signed-off-by: Dirk Behme CC: Andy Fleming CC: Fabio Estevam --- drivers/mmc/fsl_esdhc.c | 61 ++++++++++++++++++++++++++++++++++++++++------ include/fsl_esdhc.h | 4 ++- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 30db030..694d6fd 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -259,6 +259,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { uint xfertyp; uint irqstat; + uint sysctl_restore = 0; struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; @@ -279,13 +280,6 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) while (esdhc_read32(®s->prsstat) & PRSSTAT_DLA) ; - /* Wait at least 8 SD clock cycles before the next command */ - /* - * Note: This is way more than 8 cycles, but 1ms seems to - * resolve timing issues with some cards - */ - udelay(1000); - /* Set up for a data transfer if we have one */ if (data) { int err; @@ -298,6 +292,14 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) /* Figure out the transfer arguments */ xfertyp = esdhc_xfertyp(cmd, data); + /* ESDHC errata ENGcm03648: Turn off auto-clock gate for commands + * with busy signaling and no data + */ + if (!data && (cmd->resp_type & MMC_RSP_BUSY)) { + sysctl_restore = esdhc_read32(®s->sysctl); + esdhc_write32(®s->sysctl, sysctl_restore | 0xF); + } + /* Send the command */ esdhc_write32(®s->cmdarg, cmd->cmdarg); #if defined(CONFIG_FSL_USDHC) @@ -307,19 +309,62 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) #else esdhc_write32(®s->xfertyp, xfertyp); #endif + + /* Mask all irqs */ + esdhc_write32(®s->irqsigen, 0); + /* Wait for the command to complete */ - while (!(esdhc_read32(®s->irqstat) & IRQSTAT_CC)) + while (!(esdhc_read32(®s->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE))) ; irqstat = esdhc_read32(®s->irqstat); esdhc_write32(®s->irqstat, irqstat); + /* Reset CMD and DATA portions on error */ + if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) { + esdhc_write32(®s->sysctl, esdhc_read32(®s->sysctl) | + SYSCTL_RSTC); + while (esdhc_read32(®s->sysctl) & SYSCTL_RSTC) + ; + + if (data) { + esdhc_write32(®s->sysctl, + esdhc_read32(®s->sysctl) | + SYSCTL_RSTD); + while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTD)) + ; + } + + /* Restore auto-clock gate if error */ + if (!data && (cmd->resp_type & MMC_RSP_BUSY)) + esdhc_write32(®s->sysctl, sysctl_restore); + } + 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(®s->prsstat) & + PRSSTAT_DAT0)) { + udelay(100); + timeout--; + } + + esdhc_write32(®s->sysctl, sysctl_restore); + + 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; diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index 8418bf7..0e26558 100644 --- a/include/fsl_esdhc.h +++ b/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)