Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3580242imu; Fri, 30 Nov 2018 02:43:25 -0800 (PST) X-Google-Smtp-Source: AFSGD/VAdyPreXKsSlyapG8FNAOlDuxFKSHi6Jg1GELmZ0wRP26BVbi8Fg+wEoFP6vZ29Nlv85kG X-Received: by 2002:a17:902:5ac2:: with SMTP id g2mr5174724plm.313.1543574605125; Fri, 30 Nov 2018 02:43:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543574605; cv=none; d=google.com; s=arc-20160816; b=y+GLkIGn455zo3+/3gzDgRhiX+NBqdBorxHgItRDY2l6Rxn3dxqbvY1bV2ih3C3Ayw 2VQln803q70B64CoBwTKjKBne+DjxwBMj81ThfSJgfbHOYwWykLEubPQZfKkOrmVqSzX O5bOMVpUrgeqag14wDlDD36GV9/9ICSeAr4Mq97bEtlbScZC8+qxcUqQ/uuWCjCzWtik Wf9W2GTe85kL/5ax96MUU9tZDG0MuC+ZGnOeWeHPvEFwkooNi/wBVwkZlHANzWYkmadI 3r4asrxbd7s4na7q8lVOeWAcqsQg7caFTSCk4m6KRhKC9minCwyRqW3x/eJaprZzS+zP H83w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature; bh=U91mKi6HoNFNTcHtM73VB2MusvpwNeLdfmx2NJ6ePTU=; b=fW0YGmyR6mdqjqnWMAWBHIfSAovmFA4mb2+uACHvaHOIdj+rwfyVViw/2OlZ6kDHDt L1Fc79VrBegcxSDQVuZfY8eV5cwT79ZKBtbbx8GM9JniXgnbce+JC+R387HXr1DClS57 WmTM8j2ry4KzVTNBqsmyfxAkMkbVnn/qHXYg9M+CyeGFtw5klZdRAraEV3cF5CRuZfRR EUcWKA3ZHTRclA1JDOOje/gj3L3cWfzsJIEWsWj3dLMso2j0pRz+uiXlvJBtyWVPp724 ykoBPBkzkAQooqc8OJnuexPIN2ZX1BZI4UICvFAFp1S72uXzffQDajmvv/GcWoHzHsJS XnHg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=OA7l+PDN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u5si4389889pgr.316.2018.11.30.02.43.10; Fri, 30 Nov 2018 02:43:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=OA7l+PDN; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726852AbeK3VvN (ORCPT + 99 others); Fri, 30 Nov 2018 16:51:13 -0500 Received: from fllv0015.ext.ti.com ([198.47.19.141]:36994 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726521AbeK3VvN (ORCPT ); Fri, 30 Nov 2018 16:51:13 -0500 Received: from lelv0265.itg.ti.com ([10.180.67.224]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id wAUAgGjP039588; Fri, 30 Nov 2018 04:42:16 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1543574536; bh=U91mKi6HoNFNTcHtM73VB2MusvpwNeLdfmx2NJ6ePTU=; h=Subject:To:CC:References:From:Date:In-Reply-To; b=OA7l+PDNruM4LVc3fdEydpQzzGKeJCbIJS/1wHx9vUEqQ+cP55ZuiV6TmMPCwsDC/ IHNaSIjWySbtfuKi9Np5I/vfmmLwIpzyDWwtVInxqb3b/l0/i/A70/gILokD9EgMeM ufSFaL8WcfYmT1M9XYAZ2wymbGlg4Iq0y/xURmzY= Received: from DFLE104.ent.ti.com (dfle104.ent.ti.com [10.64.6.25]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id wAUAgFwG057105 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 30 Nov 2018 04:42:16 -0600 Received: from DFLE110.ent.ti.com (10.64.6.31) by DFLE104.ent.ti.com (10.64.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1591.10; Fri, 30 Nov 2018 04:42:15 -0600 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE110.ent.ti.com (10.64.6.31) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1591.10 via Frontend Transport; Fri, 30 Nov 2018 04:42:15 -0600 Received: from [172.24.190.215] (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id wAUAgDQ3003671; Fri, 30 Nov 2018 04:42:14 -0600 Subject: Re: [PATCH] mmc: sdhci-omap: Workaround errata regarding SDR104/HS200 tuning failures (i929) To: , CC: , , References: <20181129190503.6040-1-faiz_abbas@ti.com> From: Faiz Abbas Message-ID: <0ede4e5c-0447-87ef-440e-871d076232eb@ti.com> Date: Fri, 30 Nov 2018 16:14:59 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: <20181129190503.6040-1-faiz_abbas@ti.com> Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 7bit X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, I forgot to mention that this patch goes on top of my series "Tuning Fixes for sdhci-omap" series. https://patchwork.kernel.org/project/linux-mmc/list/?series=44725 Thanks, Faiz On 30/11/18 12:35 AM, Faiz Abbas wrote: > Errata i929 in certain OMAP5/DRA7XX/AM57XX silicon revisions > (SPRZ426D - November 2014 - Revised February 2018 [1]) mentions > unexpected tuning pattern errors. A small failure band may be present > in the tuning range which may be missed by the current algorithm. > Furthermore, the failure bands vary with temperature leading to > different optimum tuning values for different temperatures. > > As suggested in the related Application Report (SPRACA9B - October 2017 > - Revised July 2018 [2]), tuning should be done in two stages. > In stage 1, assign the optimum ratio in the maximum pass window for the > current temperature. In stage 2, if the chosen value is close to the > small failure band, move away from it in the appropriate direction. > > References: > [1] http://www.ti.com/lit/pdf/sprz426 > [2] http://www.ti.com/lit/pdf/SPRACA9 > > Signed-off-by: Faiz Abbas > --- > drivers/mmc/host/Kconfig | 2 + > drivers/mmc/host/sdhci-omap.c | 90 ++++++++++++++++++++++++++++++++++- > 2 files changed, 91 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig > index 1b58739d9744..6d3553f06f27 100644 > --- a/drivers/mmc/host/Kconfig > +++ b/drivers/mmc/host/Kconfig > @@ -969,6 +969,8 @@ config MMC_SDHCI_XENON > config MMC_SDHCI_OMAP > tristate "TI SDHCI Controller Support" > depends on MMC_SDHCI_PLTFM && OF > + select THERMAL > + select TI_SOC_THERMAL > help > This selects the Secure Digital Host Controller Interface (SDHCI) > support present in TI's DRA7 SOCs. The controller supports > diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c > index b3cb39d0db6f..9ccce7ef3a60 100644 > --- a/drivers/mmc/host/sdhci-omap.c > +++ b/drivers/mmc/host/sdhci-omap.c > @@ -27,6 +27,7 @@ > #include > #include > #include > +#include > > #include "sdhci-pltfm.h" > > @@ -286,14 +287,18 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode) > struct sdhci_host *host = mmc_priv(mmc); > struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); > struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host); > + struct thermal_zone_device *thermal_dev; > struct device *dev = omap_host->dev; > struct mmc_ios *ios = &mmc->ios; > u32 start_window = 0, max_window = 0; > + bool single_point_failure = false; > u8 cur_match, prev_match = 0; > u32 length = 0, max_len = 0; > u32 phase_delay = 0; > + int temperature; > int ret = 0; > u32 reg; > + int i; > > /* clock tuning is not needed for upto 52MHz */ > if (ios->clock <= 52000000) > @@ -303,6 +308,16 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode) > if (ios->timing == MMC_TIMING_UHS_SDR50 && !(reg & CAPA2_TSDR50)) > return 0; > > + thermal_dev = thermal_zone_get_zone_by_name("cpu_thermal"); > + if (IS_ERR(thermal_dev)) { > + dev_err(dev, "Unable to get thermal zone for tuning\n"); > + return PTR_ERR(thermal_dev); > + } > + > + ret = thermal_zone_get_temp(thermal_dev, &temperature); > + if (ret) > + return ret; > + > reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_DLL); > reg |= DLL_SWT; > sdhci_omap_writel(omap_host, SDHCI_OMAP_DLL, reg); > @@ -317,6 +332,11 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode) > > omap_host->is_tuning = true; > > + /* > + * Stage 1: Search for a maximum pass window ignoring any > + * any single point failures. If the tuning value ends up > + * near it, move away from it in stage 2 below > + */ > while (phase_delay <= MAX_PHASE_DELAY) { > sdhci_omap_set_dll(omap_host, phase_delay); > > @@ -324,10 +344,15 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode) > if (cur_match) { > if (prev_match) { > length++; > + } else if (single_point_failure) { > + /* ignore single point failure */ > + length++; > } else { > start_window = phase_delay; > length = 1; > } > + } else { > + single_point_failure = prev_match; > } > > if (length > max_len) { > @@ -345,13 +370,76 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode) > goto tuning_error; > } > > + /* > + * Assign tuning value as a ratio of maximum pass window based > + * on temperature > + */ > + if (temperature < -20000) > + phase_delay = min(max_window + 4 * max_len - 24, > + max_window + > + DIV_ROUND_UP(13 * max_len, 16) * 4); > + else if (temperature < 20000) > + phase_delay = max_window + DIV_ROUND_UP(9 * max_len, 16) * 4; > + else if (temperature < 40000) > + phase_delay = max_window + DIV_ROUND_UP(8 * max_len, 16) * 4; > + else if (temperature < 70000) > + phase_delay = max_window + DIV_ROUND_UP(7 * max_len, 16) * 4; > + else if (temperature < 90000) > + phase_delay = max_window + DIV_ROUND_UP(5 * max_len, 16) * 4; > + else if (temperature < 120000) > + phase_delay = max_window + DIV_ROUND_UP(4 * max_len, 16) * 4; > + else > + phase_delay = max_window + DIV_ROUND_UP(3 * max_len, 16) * 4; > + > + /* > + * Stage 2: Search for a single point failure near the chosen tuning > + * value in two steps. First in the +3 to +10 range and then in the > + * +2 to -10 range. If found, move away from it in the appropriate > + * direction by the appropriate amount depending on the temperature. > + */ > + for (i = 3; i <= 10; i++) { > + sdhci_omap_set_dll(omap_host, phase_delay + i); > + > + if (mmc_send_tuning(mmc, opcode, NULL)) { > + if (temperature < 10000) > + phase_delay += i + 6; > + else if (temperature < 20000) > + phase_delay += i - 12; > + else if (temperature < 70000) > + phase_delay += i - 8; > + else > + phase_delay += i - 6; > + > + goto single_failure_found; > + } > + } > + > + for (i = 2; i >= -10; i--) { > + sdhci_omap_set_dll(omap_host, phase_delay + i); > + > + if (mmc_send_tuning(mmc, opcode, NULL)) { > + if (temperature < 10000) > + phase_delay += i + 12; > + else if (temperature < 20000) > + phase_delay += i + 8; > + else if (temperature < 70000) > + phase_delay += i + 8; > + else if (temperature < 90000) > + phase_delay += i + 10; > + else > + phase_delay += i + 12; > + > + goto single_failure_found; > + } > + } > + > +single_failure_found: > reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12); > if (!(reg & AC12_SCLK_SEL)) { > ret = -EIO; > goto tuning_error; > } > > - phase_delay = max_window + 4 * (max_len >> 1); > sdhci_omap_set_dll(omap_host, phase_delay); > > omap_host->is_tuning = false; >