All of lore.kernel.org
 help / color / mirror / Atom feed
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.