From: Cool Lee <cool_lee@aspeedtech.com>
To: <andrew@codeconstruct.com.au>, <adrian.hunter@intel.com>,
<ulf.hansson@linaro.org>, <joel@jms.id.au>,
<p.zabel@pengutronix.de>, <linux-aspeed@lists.ozlabs.org>,
<openbmc@lists.ozlabs.org>, <linux-mmc@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>
Subject: [PATCH 2/8] mmc: sdhci-of-aspeed: Add runtime tuning
Date: Sun, 15 Jun 2025 11:57:57 +0800 [thread overview]
Message-ID: <20250615035803.3752235-3-cool_lee@aspeedtech.com> (raw)
In-Reply-To: <20250615035803.3752235-1-cool_lee@aspeedtech.com>
Add support for runtime tuning in the Aspeed SDHCI driver.
Using the timing phase register to adjust the clock phase with mmc
tuning command to find the left and right boundary.
Signed-off-by: Cool Lee <cool_lee@aspeedtech.com>
---
drivers/mmc/host/sdhci-of-aspeed.c | 68 ++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
index 01bc574272eb..5e5ae1894456 100644
--- a/drivers/mmc/host/sdhci-of-aspeed.c
+++ b/drivers/mmc/host/sdhci-of-aspeed.c
@@ -24,6 +24,7 @@
#define ASPEED_SDC_PHASE 0xf4
#define ASPEED_SDC_S1_PHASE_IN GENMASK(25, 21)
#define ASPEED_SDC_S0_PHASE_IN GENMASK(20, 16)
+#define ASPEED_SDC_S0_PHASE_IN_SHIFT 16
#define ASPEED_SDC_S1_PHASE_OUT GENMASK(15, 11)
#define ASPEED_SDC_S1_PHASE_IN_EN BIT(10)
#define ASPEED_SDC_S1_PHASE_OUT_EN GENMASK(9, 8)
@@ -375,6 +376,72 @@ static void aspeed_sdhci_reset(struct sdhci_host *host, u8 mask)
sdhci_reset(host, mask);
}
+static int aspeed_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
+{
+ struct sdhci_pltfm_host *pltfm_priv;
+ struct aspeed_sdhci *sdhci;
+ struct aspeed_sdc *sdc;
+ struct device *dev;
+
+ u32 val, left, right, edge;
+ u32 window, oldwindow = 0, center;
+ u32 in_phase, out_phase, enable_mask, inverted = 0;
+
+ dev = mmc_dev(host->mmc);
+ pltfm_priv = sdhci_priv(host);
+ sdhci = sdhci_pltfm_priv(pltfm_priv);
+ sdc = sdhci->parent;
+
+ out_phase = readl(sdc->regs + ASPEED_SDC_PHASE) & ASPEED_SDC_S0_PHASE_OUT;
+
+ enable_mask = ASPEED_SDC_S0_PHASE_OUT_EN | ASPEED_SDC_S0_PHASE_IN_EN;
+
+ /*
+ * There are two window upon clock rising and falling edge.
+ * Iterate each tap delay to find the valid window and choose the
+ * bigger one, set the tap delay at the middle of window.
+ */
+ for (edge = 0; edge < 2; edge++) {
+ if (edge == 1)
+ inverted = ASPEED_SDHCI_TAP_PARAM_INVERT_CLK;
+
+ val = (out_phase | enable_mask | (inverted << ASPEED_SDC_S0_PHASE_IN_SHIFT));
+
+ /* find the left boundary */
+ for (left = 0; left < ASPEED_SDHCI_NR_TAPS + 1; left++) {
+ in_phase = val | (left << ASPEED_SDC_S0_PHASE_IN_SHIFT);
+ writel(in_phase, sdc->regs + ASPEED_SDC_PHASE);
+
+ if (!mmc_send_tuning(host->mmc, opcode, NULL))
+ break;
+ }
+
+ /* find the right boundary */
+ for (right = left + 1; right < ASPEED_SDHCI_NR_TAPS + 1; right++) {
+ in_phase = val | (right << ASPEED_SDC_S0_PHASE_IN_SHIFT);
+ writel(in_phase, sdc->regs + ASPEED_SDC_PHASE);
+
+ if (mmc_send_tuning(host->mmc, opcode, NULL))
+ break;
+ }
+
+ window = right - left;
+ dev_info(dev, "tuning window = %d\n", window);
+
+ if (window > oldwindow) {
+ oldwindow = window;
+ center = (((right - 1) + left) / 2) | inverted;
+ }
+ }
+
+ val = (out_phase | enable_mask | (center << ASPEED_SDC_S0_PHASE_IN_SHIFT));
+ writel(val, sdc->regs + ASPEED_SDC_PHASE);
+
+ dev_info(dev, "tuning result=%x\n", val);
+
+ return mmc_send_tuning(host->mmc, opcode, NULL);
+}
+
static const struct sdhci_ops aspeed_sdhci_ops = {
.read_l = aspeed_sdhci_readl,
.set_clock = aspeed_sdhci_set_clock,
@@ -383,6 +450,7 @@ static const struct sdhci_ops aspeed_sdhci_ops = {
.get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
.reset = aspeed_sdhci_reset,
.set_uhs_signaling = sdhci_set_uhs_signaling,
+ .platform_execute_tuning = aspeed_sdhci_execute_tuning,
};
static const struct sdhci_pltfm_data aspeed_sdhci_pdata = {
--
2.34.1
next prev parent reply other threads:[~2025-06-15 3:58 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-15 3:57 [PATCH 0/8] Aspeed SDHCI driver workaround and auto tune Cool Lee
2025-06-15 3:57 ` [PATCH 1/8] mmc: sdhci-of-aspeed: Fix sdhci software reset can't be cleared issue Cool Lee
2025-06-16 13:22 ` Philipp Zabel
2025-06-18 1:34 ` Cool Lee
2025-06-18 2:14 ` Andrew Jeffery
2025-06-19 6:53 ` Cool Lee
2025-06-20 7:43 ` Andrew Jeffery
2025-06-21 8:29 ` Cool Lee
2025-06-15 3:57 ` Cool Lee [this message]
2025-06-18 2:31 ` [PATCH 2/8] mmc: sdhci-of-aspeed: Add runtime tuning Andrew Jeffery
2025-06-19 6:57 ` Cool Lee
2025-06-15 3:57 ` [PATCH 3/8] mmc: sdhci-of-aspeed: Patch HOST_CONTROL2 register missing after top reset Cool Lee
2025-06-18 2:32 ` Andrew Jeffery
2025-06-19 6:57 ` Cool Lee
2025-06-15 3:57 ` [PATCH 4/8] mmc: sdhci-of-aspeed: Get max clockk by using default api Cool Lee
2025-06-18 2:39 ` Andrew Jeffery
2025-06-20 8:18 ` Cool Lee
2025-06-15 3:58 ` [PATCH 5/8] mmc: sdhci-of-aspeed: Fix null pointer Cool Lee
2025-06-18 2:49 ` Andrew Jeffery
2025-06-20 8:18 ` Cool Lee
2025-06-15 3:58 ` [PATCH 6/8] mmc: sdhci-of-aspeed: Add output timing phase tuning Cool Lee
2025-06-18 2:51 ` Andrew Jeffery
2025-06-20 8:19 ` Cool Lee
2025-06-15 3:58 ` [PATCH 7/8] mmc: sdhci-of-aspeed: Remove timing phase Cool Lee
2025-06-18 2:56 ` Andrew Jeffery
2025-06-20 10:23 ` Cool Lee
2025-06-24 23:31 ` Andrew Jeffery
2025-06-25 0:22 ` Cool Lee
2025-06-25 0:23 ` Andrew Jeffery
2025-06-15 3:58 ` [PATCH 8/8] mmc: sdhci-of-aspeed: Add sdr50 support Cool Lee
2025-06-18 3:06 ` Andrew Jeffery
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250615035803.3752235-3-cool_lee@aspeedtech.com \
--to=cool_lee@aspeedtech.com \
--cc=adrian.hunter@intel.com \
--cc=andrew@codeconstruct.com.au \
--cc=joel@jms.id.au \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-aspeed@lists.ozlabs.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=openbmc@lists.ozlabs.org \
--cc=p.zabel@pengutronix.de \
--cc=ulf.hansson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®