From patchwork Tue Jul 2 08:53:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Jacques Hiblot X-Patchwork-Id: 1126084 X-Patchwork-Delegate: van.freenix@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="UcFBuetv"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 45dJ7R4Qx7z9s00 for ; Tue, 2 Jul 2019 18:58:43 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 35524C21E15; Tue, 2 Jul 2019 08:56:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 85911C21D8A; Tue, 2 Jul 2019 08:56:58 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 4213AC21E29; Tue, 2 Jul 2019 08:54:18 +0000 (UTC) Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248]) by lists.denx.de (Postfix) with ESMTPS id 1BC2DC21DD3 for ; Tue, 2 Jul 2019 08:54:14 +0000 (UTC) Received: from fllv0035.itg.ti.com ([10.64.41.0]) by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id x628sDlT081903; Tue, 2 Jul 2019 03:54:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1562057653; bh=iPCPQH14s//GSowm1f35/kGXC8KmpNV/D+REnPeDrIw=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=UcFBuetvkk6gf91B5qcFc/82kgIQF13gq3fRkWEtSOcwVJlth0wwVr7N0r/Bu1KZs 4ujleAX2Du5P1mXT7xZs9UXokKmKOjI3Gd7AP888oaqyrfVSYfeR1+cfhBAsHqWePY 9oegTjJ0MXZDCIt7/kzx+x4J+b2LTTJlgtC7fndA= Received: from DLEE107.ent.ti.com (dlee107.ent.ti.com [157.170.170.37]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id x628sDcV108513 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 2 Jul 2019 03:54:13 -0500 Received: from DLEE110.ent.ti.com (157.170.170.21) by DLEE107.ent.ti.com (157.170.170.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5; Tue, 2 Jul 2019 03:54:13 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE110.ent.ti.com (157.170.170.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1713.5 via Frontend Transport; Tue, 2 Jul 2019 03:54:13 -0500 Received: from localhost (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id x628sCLK095491; Tue, 2 Jul 2019 03:54:12 -0500 From: Jean-Jacques Hiblot To: Date: Tue, 2 Jul 2019 10:53:56 +0200 Message-ID: <20190702085358.27368-10-jjhiblot@ti.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190702085358.27368-1-jjhiblot@ti.com> References: <20190702085358.27368-1-jjhiblot@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 09/11] mmc: During a switch, poll on dat0 if available and check the final status X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" The switch operation can sometimes make the bus unreliable, in that case the send_status parameter should be false to indicate not to poll using CMD13. If polling on dat0 is possible, we should use it to detect the end of the operation. At the end of the operation it is safe to use CMD13 to get the status of the card. It is important to do so because the operation may have failed. Signed-off-by: Jean-Jacques Hiblot --- Changes in v2: None drivers/mmc/mmc.c | 49 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index e5cee7dbc8..1ad35fff7d 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -746,6 +746,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value, bool send_status) { + unsigned int status, start; struct mmc_cmd cmd; int timeout = DEFAULT_CMD6_TIMEOUT_MS; bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) && @@ -765,25 +766,47 @@ static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value, (index << 16) | (value << 8); - while (retries > 0) { + do { ret = mmc_send_cmd(mmc, &cmd, NULL); + } while (ret && retries-- > 0); - if (ret) { - retries--; - continue; - } + if (ret) + return ret; - if (!send_status) { - mdelay(50); - return 0; - } + start = get_timer(0); - /* Waiting for the ready status */ - return mmc_poll_for_busy(mmc, timeout); - } + /* poll dat0 for rdy/buys status */ + ret = mmc_wait_dat0(mmc, 1, timeout); + if (ret && ret != -ENOSYS) + return ret; - return ret; + /* + * In cases when not allowed to poll by using CMD13 or because we aren't + * capable of polling by using mmc_wait_dat0, then rely on waiting the + * stated timeout to be sufficient. + */ + if (ret == -ENOSYS && !send_status) + mdelay(timeout); + + /* Finally wait until the card is ready or indicates a failure + * to switch. It doesn't hurt to use CMD13 here even if send_status + * is false, because by now (after 'timeout' ms) the bus should be + * reliable. + */ + do { + ret = mmc_send_status(mmc, &status); + + if (!ret && (status & MMC_STATUS_SWITCH_ERROR)) { + pr_debug("switch failed %d/%d/0x%x !\n", set, index, + value); + return -EIO; + } + if (!ret && (status & MMC_STATUS_RDY_FOR_DATA)) + return 0; + udelay(100); + } while (get_timer(start) < timeout); + return -ETIMEDOUT; } int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)