* [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM
@ 2026-10-21 23:33 Matthew Schwartz
2026-10-30 10:53 ` BenChuang[莊智量]
2026-11-04 11:13 ` Adrian Hunter
0 siblings, 2 replies; 5+ messages in thread
From: Matthew Schwartz @ 2026-10-21 23:33 UTC (permalink / raw)
To: Adrian Hunter, Ulf Hansson
Cc: linux-mmc, linux-kernel, Victor Shih, Lucas Lai, Ben Chuang,
Matthew Schwartz
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
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM
2026-10-21 23:33 [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM Matthew Schwartz
@ 2026-10-30 10:53 ` BenChuang[莊智量]
2026-11-04 18:48 ` Matthew Schwartz
2026-11-04 11:13 ` Adrian Hunter
1 sibling, 1 reply; 5+ messages in thread
From: BenChuang[莊智量] @ 2026-10-30 10:53 UTC (permalink / raw)
To: Matthew Schwartz, Adrian Hunter, Ulf Hansson
Cc: linux-mmc, linux-kernel, Victor Shih, Lucas Lai
> -----Original Message-----
> From: Matthew Schwartz <matthew.schwartz@linux.dev>
> Sent: Thursday, October 22, 2026 7:33 AM
> 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>; BenChuang[莊智量] <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
>
> 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>
Hi Matthew,
Thanks for the patch.
I checked the GL9767 register definition. Register 0x8CC is the UHS-II
Status Register, and bit 13 is documented as
UHS2_WAKEUP_ACTIVATE.
I was able to reproduce the "SDHCI_UHS2_CAPS_PTR(65535) is wrong" issue
on my GL9767 test system, and I can no longer reproduce it with this
patch applied.
Tested-by: Ben Chuang <ben.chuang@genesyslogic.com.tw>
> ---
> 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)
maybe PCIE_GLI_9767_UHS2_STS and PCIE_GLI_9767_UHS2_STS_WAKEUP_ACTIVATE
> +
> #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));
> +}
> +
One thing I was curious about.
The commit message mentions an observed settling time of approximately
250-300 us, while the polling loop allows up to 10 ms before reporting
a timeout.
I assume the timeout is intentionally conservative, but I was wondering
whether there was any particular reason for choosing 10 ms.
Best regards,
Ben Chuang
> 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
________________________________
Genesys Logic Email Confidentiality Notice:
This mail and any attachments may contain information that is confidential, proprietary, privileged or otherwise protected by law. The mail is intended solely for the named addressee (or a person responsible for delivering it to the addressee). If you are not the intended recipient of this mail, you are not authorized to read, print, copy or disseminate this mail.
If you have received this email in error, please notify us immediately by reply email and immediately delete this message and any attachments from your system. Please be noted that any unauthorized use, dissemination, distribution or copying of this email is strictly prohibited.
________________________________
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM
2026-10-21 23:33 [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM Matthew Schwartz
2026-10-30 10:53 ` BenChuang[莊智量]
@ 2026-11-04 11:13 ` Adrian Hunter
2026-11-04 18:49 ` Matthew Schwartz
1 sibling, 1 reply; 5+ messages in thread
From: Adrian Hunter @ 2026-11-04 11:13 UTC (permalink / raw)
To: Matthew Schwartz, Ulf Hansson
Cc: linux-mmc, linux-kernel, Victor Shih, Lucas Lai, Ben Chuang
On 22/10/2026 02:33, Matthew Schwartz wrote:
> 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>
One comment below, otherwise:
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> ---
> 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))
Doesn't look like this needs to be atomic
> + 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);
> }
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM
2026-10-30 10:53 ` BenChuang[莊智量]
@ 2026-11-04 18:48 ` Matthew Schwartz
0 siblings, 0 replies; 5+ messages in thread
From: Matthew Schwartz @ 2026-11-04 18:48 UTC (permalink / raw)
To: BenChuang[莊智量], Adrian Hunter, Ulf Hansson
Cc: linux-mmc, linux-kernel, Victor Shih, Lucas Lai
On 10/30/26 3:53 AM, BenChuang[莊智量] wrote:
>
>
>> -----Original Message-----
>> From: Matthew Schwartz <matthew.schwartz@linux.dev>
>> Sent: Thursday, October 22, 2026 7:33 AM
>> 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>; BenChuang[莊智量] <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
>>
>> 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>
>
> Hi Matthew,
>
> Thanks for the patch.
>
> I checked the GL9767 register definition. Register 0x8CC is the UHS-II
> Status Register, and bit 13 is documented as
> UHS2_WAKEUP_ACTIVATE.
>
> I was able to reproduce the "SDHCI_UHS2_CAPS_PTR(65535) is wrong" issue
> on my GL9767 test system, and I can no longer reproduce it with this
> patch applied.
Thanks for looking up the definition and for testing.
>
> Tested-by: Ben Chuang <ben.chuang@genesyslogic.com.tw>
>
>> ---
>> 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)
>
> maybe PCIE_GLI_9767_UHS2_STS and PCIE_GLI_9767_UHS2_STS_WAKEUP_ACTIVATE
Sounds good, will do in v2.
>
>> +
>> #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));
>> +}
>> +
>
> One thing I was curious about.
>
> The commit message mentions an observed settling time of approximately
> 250-300 us, while the polling loop allows up to 10 ms before reporting
> a timeout.
>
> I assume the timeout is intentionally conservative, but I was wondering
> whether there was any particular reason for choosing 10 ms.
No particular reason beyond headroom. I only had the measured 250-300 us
to go on, so I picked a ceiling well above that which is only reached if
the bit never clears. If the GL9767 spec gives a maximum wakeup time,
I'm happy to use that instead.
>
> Best regards,
> Ben Chuang
>
>> 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
>
> ________________________________
>
> Genesys Logic Email Confidentiality Notice:
> This mail and any attachments may contain information that is confidential, proprietary, privileged or otherwise protected by law. The mail is intended solely for the named addressee (or a person responsible for delivering it to the addressee). If you are not the intended recipient of this mail, you are not authorized to read, print, copy or disseminate this mail.
>
> If you have received this email in error, please notify us immediately by reply email and immediately delete this message and any attachments from your system. Please be noted that any unauthorized use, dissemination, distribution or copying of this email is strictly prohibited.
> ________________________________
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM
2026-11-04 11:13 ` Adrian Hunter
@ 2026-11-04 18:49 ` Matthew Schwartz
0 siblings, 0 replies; 5+ messages in thread
From: Matthew Schwartz @ 2026-11-04 18:49 UTC (permalink / raw)
To: Adrian Hunter, Ulf Hansson
Cc: linux-mmc, linux-kernel, Victor Shih, Lucas Lai, Ben Chuang
On 11/4/26 3:13 AM, Adrian Hunter wrote:
> On 22/10/2026 02:33, Matthew Schwartz wrote:
>> 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>
>
> One comment below, otherwise:
>
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
>
>> ---
>> 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))
>
> Doesn't look like this needs to be atomic
Makes sense, will fix in v2.
>
>> + 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);
>> }
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-04 18:49 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21 23:33 [PATCH] mmc: sdhci-pci-gli: GL9767: Wait for UHS-II PHY before LPM Matthew Schwartz
2026-10-30 10:53 ` BenChuang[莊智量]
2026-11-04 18:48 ` Matthew Schwartz
2026-11-04 11:13 ` Adrian Hunter
2026-11-04 18:49 ` Matthew Schwartz
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®