From patchwork Wed Oct 11 20:46:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 10000641 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 6DB3B6037F for ; Wed, 11 Oct 2017 20:46:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 60BA728B23 for ; Wed, 11 Oct 2017 20:46:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 54E9328B6B; Wed, 11 Oct 2017 20:46:31 +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.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham 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 DB47728B23 for ; Wed, 11 Oct 2017 20:46:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752673AbdJKUqa (ORCPT ); Wed, 11 Oct 2017 16:46:30 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:52628 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752178AbdJKUq3 (ORCPT ); Wed, 11 Oct 2017 16:46:29 -0400 Received: by mail-wm0-f65.google.com with SMTP id k4so8206010wmc.1 for ; Wed, 11 Oct 2017 13:46:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:cc:from:subject:message-id:date:user-agent:mime-version :content-transfer-encoding; bh=B7ytT0Og07zGOcWnQgkWjW676smdxVHLnKeMicD5OI0=; b=I+zBNFfPBawp5+ewsozNmO1Zj1MzJIl0Qv/8NG/W6R3hm4K7y5SSdyZoj7EruQA41f dT1dn1g9eEno7VqICu/6MLrlYB9vVESqOhgQU6HvOvAfSrVVzNLy2PnJoLpx57spouTi iTSiiq/QbvyjkrZfBYQw1yXWx6tBZZVqNoHfnHXKQ4roC3NadG56IWWiA4PfUSYvwSEv zxIW9Jvl7LODbWgzK9owW9/ZuAPjq9XmBsnD9ElQpYEM9DUzKDbpaQZeJjLi+SaX61pv j8g8Aqz4e3Si8B/829+B9D0TytllICifhPV4b8IN1M57pHLlMBk+vuWVgb4IbAX9WbLa aT/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:cc:from:subject:message-id:date:user-agent :mime-version:content-transfer-encoding; bh=B7ytT0Og07zGOcWnQgkWjW676smdxVHLnKeMicD5OI0=; b=mopS2o+33Iu3O/GWfWe3nGtRxtnVnVv9kwbUkBFRxnikvdRYa22bST1WPdoF4GPvze oLEimqF8NkFL2JHioaw/7Uy5rZySLjVQgiKqL7+1el41PtgHBXfM5icEuybWbTzqquhX Z6vw38ClxJBRU6rgpCi6OvmVV5dGmmHxayS+yzT6cRZZXooobh/cMgAVrpkXjqJf/ffS uW2oYHWYmy/RpMM0rVxZt4+SZ4VhvbmFZUEb/ds8QPI2li9yfAh20jFi/3FZUFHUmYv3 a89bYttzz1NxH9SmThTCwnNS3HMj9EcGgou+3yvfaExTl9V81X7U0Xrm04psnQYLZQLN DMsw== X-Gm-Message-State: AMCzsaXaHHc+ooIl1Wl6VzBfl/EbmKJ3AfG9AlGIw31Lh/apR42VfqxG U1Qs7whbLmeWrZ1fcHIwyq0= X-Google-Smtp-Source: AOwi7QB1wwSsotp9KRmbYGMh+pcMtgq78gFbDcgGcJIC8Ik48q0UzzdQHq8lsfxospSSxvGh0LomsA== X-Received: by 10.28.143.130 with SMTP id r124mr151303wmd.122.1507754787896; Wed, 11 Oct 2017 13:46:27 -0700 (PDT) Received: from ?IPv6:2003:ea:8bcb:c500:39a1:8f52:80a0:2d0e? (p200300EA8BCBC50039A18F5280A02D0E.dip0.t-ipconnect.de. [2003:ea:8bcb:c500:39a1:8f52:80a0:2d0e]) by smtp.googlemail.com with ESMTPSA id o18sm6757743wrc.45.2017.10.11.13.46.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 13:46:27 -0700 (PDT) To: Jerome Brunet Cc: "linux-mmc@vger.kernel.org" , "open list:ARM/Amlogic Meson..." , Kevin Hilman From: Heiner Kallweit Subject: eMMC tuning issue on Odroid C2 and a possible solution Message-ID: Date: Wed, 11 Oct 2017 22:46:19 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 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 Hi Jerome, we have the known issue that the latest next kernel still fails on Odroid C2 with a 128GB eMMC card (w/o adjusting the initial tx phase). I found the time to dig a little deeper into it and reason is that there are certain rx/tx phase combinations which are perfectly fine when tuning but fail in real life. Don't ask me how this can happen, I just see it happen. To deal with such cases I added some code to avoid known invalid phase values when retuning. In addition I added some code to deal with the following (more or less corner) case: Let's say we have rx = 0° and tx = 0° and working is only combination rx = 180° and tx = 180°. Then just tuning rx only or tx only will never result in a working combination. Following patch makes my system work. I just see one CRC error when the initally tuned rx/tx phase combination fails and then the retuning results in a stable system w/o further errors. I'd appreciate if you could check that this patch doesn't break any of your systems. Rgds, Heiner --- drivers/mmc/host/meson-gx-mmc.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 85745ef1..95cb439d 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -120,6 +120,7 @@ #define SD_EMMC_DESC_CHAIN_MODE BIT(1) #define MUX_CLK_NUM_PARENTS 2 +#define MAX_TUNING_ATTEMPTS 10 struct sd_emmc_desc { u32 cmd_cfg; @@ -687,15 +688,23 @@ static int meson_mmc_find_tuning_point(unsigned long *test) static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode, struct clk *clk) { - int point, ret; + int point, ret, old_phase; DECLARE_BITMAP(test, CLK_PHASE_POINT_NUM); + old_phase = clk_get_phase(clk); + if (old_phase < 0) + return old_phase; + dev_dbg(mmc_dev(mmc), "%s phase/delay tunning...\n", __clk_get_name(clk)); bitmap_zero(test, CLK_PHASE_POINT_NUM); /* Explore tuning points */ for (point = 0; point < CLK_PHASE_POINT_NUM; point++) { + /* when retuning avoid the surrounding of where we failed */ + if (mmc->doing_retune) + if (abs(point * CLK_PHASE_STEP - old_phase) <= 45) + continue; clk_set_phase(clk, point * CLK_PHASE_STEP); ret = mmc_send_tuning(mmc, opcode, NULL); if (!ret) @@ -704,8 +713,11 @@ static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode, /* Find the optimal tuning point and apply it */ point = meson_mmc_find_tuning_point(test); - if (point < 0) + if (point < 0) { + /* prevent from getting stuck if we failed */ + clk_set_phase(clk, (old_phase + 90) % 360); return point; /* tuning failed */ + } clk_set_phase(clk, point * CLK_PHASE_STEP); dev_dbg(mmc_dev(mmc), "success with phase: %d\n", @@ -716,7 +728,7 @@ static int meson_mmc_clk_phase_tuning(struct mmc_host *mmc, u32 opcode, static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) { struct meson_host *host = mmc_priv(mmc); - int ret; + int i, ret; /* * If this is the initial tuning, try to get a sane Rx starting @@ -729,11 +741,14 @@ static int meson_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) return ret; } - ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->tx_clk); - if (ret) - return ret; + for (i = 0; i < MAX_TUNING_ATTEMPTS; i++) { + meson_mmc_clk_phase_tuning(mmc, opcode, host->tx_clk); + ret = meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); + if (!ret) + return 0; + } - return meson_mmc_clk_phase_tuning(mmc, opcode, host->rx_clk); + return ret; } static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)