From: Matthew Schwartz <matthew.schwartz@linux.dev>
To: Adrian Hunter <adrian.hunter@intel.com>, Ulf Hansson <ulfh@kernel.org>
Cc: linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org,
Victor Shih <victor.shih@genesyslogic.com.tw>,
Lucas Lai <lucas.lai@genesyslogic.com.tw>,
Ben Chuang <ben.chuang@genesyslogic.com.tw>,
Matthew Schwartz <matthew.schwartz@linux.dev>
Subject: [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM
Date: Wed, 21 Oct 2026 16:33:13 -0700 [thread overview]
Message-ID: <20261021233313.247155-1-matthew.schwartz@linux.dev> (raw)
sdhci_gl9767_set_clock() re-enables low power negotiation right after
releasing the UHS-II PHY reset. If the bus then goes idle before the
PHY has settled, every SDHCI MMIO read returns all-ones for about 250
us. sdhci_uhs2_interface_detect() takes that as IF_DETECT and LANE_SYNC
set, so a UHS-I only microSD card is treated as UHS-II. The attach then
either fails with "SDHCI_UHS2_CAPS_PTR(65535) is wrong" or, if the
registers come back before the CAPS_PTR read, runs DEVICE_INIT 30 times
with a 10 second timeout each and delays card detection by 5 minutes.
Config register 0x8CC reads 0x2000 from clock enable until about 250-300
us after the PHY reset release and 0x1000 otherwise. Poll its bit 13
before re-enabling low power negotiation. The register meaning is
inferred from that behaviour, and with the wait in place 12 of 12
UHS-II probes of a UHS-I card correctly found no UHS-II interface.
Fixes: 27dd3b82557a ("mmc: sdhci-pci-gli: enable UHS-II mode for GL9767")
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
---
drivers/mmc/host/sdhci-pci-gli.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c
index b55618566d651..bd383918d27c7 100644
--- a/drivers/mmc/host/sdhci-pci-gli.c
+++ b/drivers/mmc/host/sdhci-pci-gli.c
@@ -205,6 +205,9 @@
#define PCIE_GLI_9767_COMBO_MUX_CTL_RST_EN BIT(6)
#define PCIE_GLI_9767_COMBO_MUX_CTL_WAIT_PERST_EN BIT(10)
+#define PCIE_GLI_9767_PHY_STS 0x8CC
+#define PCIE_GLI_9767_PHY_STS_UHS2_BUSY BIT(13)
+
#define PCIE_GLI_9767_PWR_MACRO_CTL 0x8D0
#define PCIE_GLI_9767_PWR_MACRO_CTL_LOW_VOLTAGE GENMASK(3, 0)
#define PCIE_GLI_9767_PWR_MACRO_CTL_LD0_LOW_OUTPUT_VOLTAGE GENMASK(15, 12)
@@ -1190,6 +1193,27 @@ static void gl9767_set_low_power_negotiation(struct pci_dev *pdev, bool enable)
gl9767_vhs_read(pdev);
}
+static u32 gl9767_read_phy_sts(struct pci_dev *pdev)
+{
+ u32 value;
+
+ pci_read_config_dword(pdev, PCIE_GLI_9767_PHY_STS, &value);
+
+ return value;
+}
+
+static void sdhci_gl9767_uhs2_wait_phy_ready(struct sdhci_host *host)
+{
+ struct sdhci_pci_slot *slot = sdhci_priv(host);
+ struct pci_dev *pdev = slot->chip->pdev;
+ u32 value;
+
+ if (read_poll_timeout_atomic(gl9767_read_phy_sts, value,
+ !(value & PCIE_GLI_9767_PHY_STS_UHS2_BUSY),
+ 10, 10000, false, pdev))
+ pr_warn("%s: UHS-II PHY not ready after reset.\n", mmc_hostname(host->mmc));
+}
+
static void sdhci_gl9767_uhs2_phy_reset(struct sdhci_host *host, bool assert)
{
struct sdhci_pci_slot *slot = sdhci_priv(host);
@@ -1276,9 +1300,12 @@ static void sdhci_gl9767_set_clock(struct sdhci_host *host, unsigned int clock)
sdhci_enable_clk(host, clk);
- if (mmc_card_uhs2(host->mmc))
+ if (mmc_card_uhs2(host->mmc)) {
/* De-assert reset */
sdhci_gl9767_uhs2_phy_reset(host, false);
+ /* Low power negotiation before the PHY settles makes MMIO read all-ones */
+ sdhci_gl9767_uhs2_wait_phy_ready(host);
+ }
gl9767_set_low_power_negotiation(pdev, true);
}
--
2.56.0
reply other threads:[~2026-10-21 23:33 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20261021233313.247155-1-matthew.schwartz@linux.dev \
--to=matthew.schwartz@linux.dev \
--cc=adrian.hunter@intel.com \
--cc=ben.chuang@genesyslogic.com.tw \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=lucas.lai@genesyslogic.com.tw \
--cc=ulfh@kernel.org \
--cc=victor.shih@genesyslogic.com.tw \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.