Received: by 2002:ab2:6857:0:b0:1ef:ffd0:ce49 with SMTP id l23csp113889lqp; Wed, 20 Mar 2024 15:40:23 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCW8tbHGTnv9YSTf5T+RuI9tr0ZV5jvLBKV2Lxpj9LS0yLyDNjmap9Dk9c7gD8/BEiGe7qTVIHh8c6QYVN/BiaVMFdbT3C4lS3NQPBR9tA== X-Google-Smtp-Source: AGHT+IF2X+OdKOBr6/lvHMtl7li1l/lDfcFnYcxpI5j8HYBvtqrG6wolsV1WT+l70er/u78oE9L/ X-Received: by 2002:a50:cc95:0:b0:566:f81:41a1 with SMTP id q21-20020a50cc95000000b005660f8141a1mr193692edi.22.1710974422823; Wed, 20 Mar 2024 15:40:22 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1710974422; cv=pass; d=google.com; s=arc-20160816; b=BaqXjIBpktNcH+yDRVwcktjRzFJb+sMX/hQdkLp0gAkmSIt8E7u0A/tRl7Dbr8ZdhO RVhv+FJ7quizrpyyRabdpswTVPto8Ne6W3Ycir9Cuu7AQQZtSsgerjw62jZVIXRfKrJp vWML1WLz1vRMo/3RkGPG07xkh+BgBjAv3Atb1/ONZnv2xmWj4WAQGNy2aqufFrWhmtn0 k+3Ki7K/DFDXE7QZ8kXZfPKOfJHvrmc7DvdxlogB+D6XrXDuRvpqmjuZE+VIABEVcDGZ fvOPiRF2oOySIQME+J1tmhMN2tKjZqvijpPfJL+ITYZraucNLJQfnbXCVU+h528ttnTn 0Wpw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=dyFwFsIDkgjVgcJ5rmXl3emgSOQ8KNOcDgyhqherJmQ=; fh=nPiSpvN2wrl2mtaHfXP0/ddrOQ6Y7VRxO8F4D5qr5ys=; b=Fw82UD52rMocG/boReROH2sPrvQ1bjQbiBA+c8lS/Njc3hHcaOv7C4EVU1D2NoTd3b 9G9GMB/u8YtNfaZVvGDG/Yy+MQbrfwPOGrfHtNyh9tN9d/FcDVG/gz0HcPNtRNzqa+jZ 5pS3GQnHNWQdiErj3G85NixqqWfUYyFW7DTYjyDPGVOqbEJ1WolBCmbHkKnjtFn9jXVw bRB+wTkdxsXT0g4MxhKLhPmYuuQHnioniCS49FX7HPbzKkkRNqLyEKWzxLHP8pKGLfC1 w0Ok5X8Hkbk3p6SMh2us4kPinf6DU52EeBtSt1f06+o8MiJtceHUgUd7RshGq+jsNrXq pYzA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=t5PEK4vx; arc=pass (i=1 spf=pass spfdomain=ti.com dkim=pass dkdomain=ti.com dmarc=pass fromdomain=ti.com); spf=pass (google.com: domain of linux-kernel+bounces-109468-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-109468-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id h41-20020a0564020ea900b005660aa17d6asi6902933eda.492.2024.03.20.15.40.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Mar 2024 15:40:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-109468-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=t5PEK4vx; arc=pass (i=1 spf=pass spfdomain=ti.com dkim=pass dkdomain=ti.com dmarc=pass fromdomain=ti.com); spf=pass (google.com: domain of linux-kernel+bounces-109468-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-109468-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 636591F22353 for ; Wed, 20 Mar 2024 22:40:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9954D126F15; Wed, 20 Mar 2024 22:38:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="t5PEK4vx" Received: from fllv0016.ext.ti.com (fllv0016.ext.ti.com [198.47.19.142]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D048686658; Wed, 20 Mar 2024 22:38:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.19.142 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710974328; cv=none; b=RzkZTe12DmhK+u7Pe3/bw9Li9FJ1I9apMk3FrnGyTNS6TIErX0o1U0+o9gcdmdkE26x4/Lubak9PYFm95zwqZMYarRNKpygVwP++fISor81Z3CzPvLJJliPQZaRb/nccd/2AnL1PIfRyDykiaalr/dVfoellJGn+h23qQ79q56A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710974328; c=relaxed/simple; bh=W1MqyVVdr5Y1Pz0nnukvP0Kr/c/ph/vv4ylS4ScKs8s=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VH0gLxqeOdWeoI3VUW80FRPpnmx8WOC5z4UQ6sMZaRnGvNgr04/SODOJ2awPOoI4iMGxA1+cJ7JwIghmHBkVu/zglg1w0iLn6yqO9osjucScnNMeP8IIvggqp7Zj2tBS7JSKDbt+ZBHlHDVwfcIJl5SCkTgnF9zpGBtl6+bS6QU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=t5PEK4vx; arc=none smtp.client-ip=198.47.19.142 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Received: from fllv0035.itg.ti.com ([10.64.41.0]) by fllv0016.ext.ti.com (8.15.2/8.15.2) with ESMTP id 42KMcbAB062291; Wed, 20 Mar 2024 17:38:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1710974317; bh=dyFwFsIDkgjVgcJ5rmXl3emgSOQ8KNOcDgyhqherJmQ=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=t5PEK4vxkg2+MG8ttAAQ3qc2cNCu8uMflwdGt4/sj7o5uqCsGMe1BJ+X5gF8mLveV GnbXLKY8ekokpzGwL8DWVyHiPAM1gaJQmVjzzPNsNUSc8fq59oOkObfwd+pUcEBmaR ZeV4NgCiflweIu2EpHafoVZlSLGg2iPmLJntB07Y= Received: from DLEE111.ent.ti.com (dlee111.ent.ti.com [157.170.170.22]) by fllv0035.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 42KMcbCQ102534 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 20 Mar 2024 17:38:37 -0500 Received: from DLEE111.ent.ti.com (157.170.170.22) by DLEE111.ent.ti.com (157.170.170.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Wed, 20 Mar 2024 17:38:37 -0500 Received: from lelvsmtp6.itg.ti.com (10.180.75.249) by DLEE111.ent.ti.com (157.170.170.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Wed, 20 Mar 2024 17:38:37 -0500 Received: from judy-hp.dhcp.ti.com (judy-hp.dhcp.ti.com [128.247.81.105]) by lelvsmtp6.itg.ti.com (8.15.2/8.15.2) with ESMTP id 42KMcbun036138; Wed, 20 Mar 2024 17:38:37 -0500 From: Judith Mendez To: Ulf Hansson , Adrian Hunter CC: Andrew Davis , , Subject: [PATCH v5 1/7] mmc: sdhci_am654: Add tuning algorithm for delay chain Date: Wed, 20 Mar 2024 17:38:31 -0500 Message-ID: <20240320223837.959900-2-jm@ti.com> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240320223837.959900-1-jm@ti.com> References: <20240320223837.959900-1-jm@ti.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Currently the sdhci_am654 driver only supports one tuning algorithm which should be used only when DLL is enabled. The ITAPDLY is selected from the largest passing window and the buffer is viewed as a circular buffer. The new algorithm should be used when the delay chain is enabled. The ITAPDLY is selected from the largest passing window and the buffer is not viewed as a circular buffer. This implementation is based off of the following paper: [1]. Also add support for multiple failing windows. [1] https://www.ti.com/lit/an/spract9/spract9.pdf Fixes: 13ebeae68ac9 ("mmc: sdhci_am654: Add support for software tuning") Signed-off-by: Judith Mendez Acked-by: Adrian Hunter --- Changelog: v4->v5: - Add dll_enable = false --- drivers/mmc/host/sdhci_am654.c | 112 +++++++++++++++++++++++++++------ 1 file changed, 92 insertions(+), 20 deletions(-) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index d659c59422e1..d8c9821b0b66 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -149,10 +149,17 @@ struct sdhci_am654_data { int strb_sel; u32 flags; u32 quirks; + bool dll_enable; #define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0) }; +struct window { + u8 start; + u8 end; + u8 length; +}; + struct sdhci_am654_driver_data { const struct sdhci_pltfm_data *pdata; u32 flags; @@ -290,10 +297,13 @@ static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock) regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val); - if (timing > MMC_TIMING_UHS_SDR25 && clock >= CLOCK_TOO_SLOW_HZ) + if (timing > MMC_TIMING_UHS_SDR25 && clock >= CLOCK_TOO_SLOW_HZ) { sdhci_am654_setup_dll(host, clock); - else + sdhci_am654->dll_enable = true; + } else { sdhci_am654_setup_delay_chain(sdhci_am654, timing); + sdhci_am654->dll_enable = false; + } regmap_update_bits(sdhci_am654->base, PHY_CTRL5, CLKBUFSEL_MASK, sdhci_am654->clkbuf_sel); @@ -408,39 +418,101 @@ static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask) return 0; } -#define ITAP_MAX 32 +#define ITAPDLY_LENGTH 32 +#define ITAPDLY_LAST_INDEX (ITAPDLY_LENGTH - 1) + +static u32 sdhci_am654_calculate_itap(struct sdhci_host *host, struct window + *fail_window, u8 num_fails, bool circular_buffer) +{ + u8 itap = 0, start_fail = 0, end_fail = 0, pass_length = 0; + u8 first_fail_start = 0, last_fail_end = 0; + struct device *dev = mmc_dev(host->mmc); + struct window pass_window = {0, 0, 0}; + int prev_fail_end = -1; + u8 i; + + if (!num_fails) + return ITAPDLY_LAST_INDEX >> 1; + + if (fail_window->length == ITAPDLY_LENGTH) { + dev_err(dev, "No passing ITAPDLY, return 0\n"); + return 0; + } + + first_fail_start = fail_window->start; + last_fail_end = fail_window[num_fails - 1].end; + + for (i = 0; i < num_fails; i++) { + start_fail = fail_window[i].start; + end_fail = fail_window[i].end; + pass_length = start_fail - (prev_fail_end + 1); + + if (pass_length > pass_window.length) { + pass_window.start = prev_fail_end + 1; + pass_window.length = pass_length; + } + prev_fail_end = end_fail; + } + + if (!circular_buffer) + pass_length = ITAPDLY_LAST_INDEX - last_fail_end; + else + pass_length = ITAPDLY_LAST_INDEX - last_fail_end + first_fail_start; + + if (pass_length > pass_window.length) { + pass_window.start = last_fail_end + 1; + pass_window.length = pass_length; + } + + if (!circular_buffer) + itap = pass_window.start + (pass_window.length >> 1); + else + itap = (pass_window.start + (pass_window.length >> 1)) % ITAPDLY_LENGTH; + + return (itap > ITAPDLY_LAST_INDEX) ? ITAPDLY_LAST_INDEX >> 1 : itap; +} + static int sdhci_am654_platform_execute_tuning(struct sdhci_host *host, u32 opcode) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); - int cur_val, prev_val = 1, fail_len = 0, pass_window = 0, pass_len; - u32 itap; + struct window fail_window[ITAPDLY_LENGTH]; + u8 curr_pass, itap; + u8 fail_index = 0; + u8 prev_pass = 1; + + memset(fail_window, 0, sizeof(fail_window)); /* Enable ITAPDLY */ regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPDLYENA_MASK, 1 << ITAPDLYENA_SHIFT); - for (itap = 0; itap < ITAP_MAX; itap++) { + for (itap = 0; itap < ITAPDLY_LENGTH; itap++) { sdhci_am654_write_itapdly(sdhci_am654, itap); - cur_val = !mmc_send_tuning(host->mmc, opcode, NULL); - if (cur_val && !prev_val) - pass_window = itap; + curr_pass = !mmc_send_tuning(host->mmc, opcode, NULL); - if (!cur_val) - fail_len++; + if (!curr_pass && prev_pass) + fail_window[fail_index].start = itap; - prev_val = cur_val; + if (!curr_pass) { + fail_window[fail_index].end = itap; + fail_window[fail_index].length++; + } + + if (curr_pass && !prev_pass) + fail_index++; + + prev_pass = curr_pass; } - /* - * Having determined the length of the failing window and start of - * the passing window calculate the length of the passing window and - * set the final value halfway through it considering the range as a - * circular buffer - */ - pass_len = ITAP_MAX - fail_len; - itap = (pass_window + (pass_len >> 1)) % ITAP_MAX; + + if (fail_window[fail_index].length != 0) + fail_index++; + + itap = sdhci_am654_calculate_itap(host, fail_window, fail_index, + sdhci_am654->dll_enable); + sdhci_am654_write_itapdly(sdhci_am654, itap); return 0; -- 2.43.2