6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Kornel Dulęba <korneld@xxxxxxxxxxxx> commit d9ed644f58670865cf067351deb71010bd87a52f upstream. To address IO performance commit f9e5b33934ce ("mmc: host: Improve I/O read/write performance for GL9763E") limited LPM negotiation to runtime suspend state. The problem is that it only flips the switch in the runtime PM resume/suspend logic. Disable LPM negotiation in gl9763e_add_host. This helps in two ways: 1. It was found that the LPM switch stays in the same position after warm reboot. Having it set in init helps with consistency. 2. Disabling LPM during the first runtime resume leaves us susceptible to the performance issue in the time window between boot and the first runtime suspend. Fixes: f9e5b33934ce ("mmc: host: Improve I/O read/write performance for GL9763E") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Kornel Dulęba <korneld@xxxxxxxxxxxx> Reviewed-by: Sven van Ashbrook <svenva@xxxxxxxxxxxx> Acked-by: Adrian Hunter <adrian.hunter@xxxxxxxxx> Link: https://lore.kernel.org/r/20231114115516.1585361-1-korneld@xxxxxxxxxxxx Signed-off-by: Ulf Hansson <ulf.hansson@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/mmc/host/sdhci-pci-gli.c | 54 ++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 25 deletions(-) --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -801,6 +801,32 @@ static void gl9763e_hs400_enhanced_strob sdhci_writel(host, val, SDHCI_GLI_9763E_HS400_ES_REG); } +static void gl9763e_set_low_power_negotiation(struct sdhci_pci_slot *slot, + bool enable) +{ + struct pci_dev *pdev = slot->chip->pdev; + u32 value; + + pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); + value &= ~GLI_9763E_VHS_REV; + value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_W); + pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); + + pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG, &value); + + if (enable) + value &= ~GLI_9763E_CFG_LPSN_DIS; + else + value |= GLI_9763E_CFG_LPSN_DIS; + + pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG, value); + + pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); + value &= ~GLI_9763E_VHS_REV; + value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); + pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); +} + static void sdhci_set_gl9763e_signaling(struct sdhci_host *host, unsigned int timing) { @@ -909,6 +935,9 @@ static int gl9763e_add_host(struct sdhci if (ret) goto cleanup; + /* Disable LPM negotiation to avoid entering L1 state. */ + gl9763e_set_low_power_negotiation(slot, false); + return 0; cleanup: @@ -960,31 +989,6 @@ static void gli_set_gl9763e(struct sdhci } #ifdef CONFIG_PM -static void gl9763e_set_low_power_negotiation(struct sdhci_pci_slot *slot, bool enable) -{ - struct pci_dev *pdev = slot->chip->pdev; - u32 value; - - pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); - value &= ~GLI_9763E_VHS_REV; - value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_W); - pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); - - pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG, &value); - - if (enable) - value &= ~GLI_9763E_CFG_LPSN_DIS; - else - value |= GLI_9763E_CFG_LPSN_DIS; - - pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG, value); - - pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); - value &= ~GLI_9763E_VHS_REV; - value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); - pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); -} - static int gl9763e_runtime_suspend(struct sdhci_pci_chip *chip) { struct sdhci_pci_slot *slot = chip->slots[0];