mmc: sdhci-pci-gli: A workaround to allow GL9750 to enter ASPM L1.2
authorVictor Shih <victor.shih@genesyslogic.com.tw>
Tue, 12 Sep 2023 09:17:10 +0000 (17:17 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 28 Nov 2023 17:20:13 +0000 (17:20 +0000)
commit d7133797e9e1b72fd89237f68cb36d745599ed86 upstream.

When GL9750 enters ASPM L1 sub-states, it will stay at L1.1 and will not
enter L1.2. The workaround is to toggle PM state to allow GL9750 to enter
ASPM L1.2.

Signed-off-by: Victor Shih <victor.shih@genesyslogic.com.tw>
Link: https://lore.kernel.org/r/20230912091710.7797-1-victorshihgli@gmail.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/mmc/host/sdhci-pci-gli.c

index 6f4dea4..044b470 100644 (file)
@@ -25,6 +25,9 @@
 #define   GLI_9750_WT_EN_ON        0x1
 #define   GLI_9750_WT_EN_OFF       0x0
 
+#define PCI_GLI_9750_PM_CTRL   0xFC
+#define   PCI_GLI_9750_PM_STATE          GENMASK(1, 0)
+
 #define SDHCI_GLI_9750_CFG2          0x848
 #define   SDHCI_GLI_9750_CFG2_L1DLY    GENMASK(28, 24)
 #define   GLI_9750_CFG2_L1DLY_VALUE    0x1F
@@ -539,8 +542,12 @@ static void sdhci_gl9750_set_clock(struct sdhci_host *host, unsigned int clock)
 
 static void gl9750_hw_setting(struct sdhci_host *host)
 {
+       struct sdhci_pci_slot *slot = sdhci_priv(host);
+       struct pci_dev *pdev;
        u32 value;
 
+       pdev = slot->chip->pdev;
+
        gl9750_wt_on(host);
 
        value = sdhci_readl(host, SDHCI_GLI_9750_CFG2);
@@ -550,6 +557,13 @@ static void gl9750_hw_setting(struct sdhci_host *host)
                            GLI_9750_CFG2_L1DLY_VALUE);
        sdhci_writel(host, value, SDHCI_GLI_9750_CFG2);
 
+       /* toggle PM state to allow GL9750 to enter ASPM L1.2 */
+       pci_read_config_dword(pdev, PCI_GLI_9750_PM_CTRL, &value);
+       value |= PCI_GLI_9750_PM_STATE;
+       pci_write_config_dword(pdev, PCI_GLI_9750_PM_CTRL, value);
+       value &= ~PCI_GLI_9750_PM_STATE;
+       pci_write_config_dword(pdev, PCI_GLI_9750_PM_CTRL, value);
+
        gl9750_wt_off(host);
 }