summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci-pci-gli.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-08-04 19:41:09 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-08-04 19:41:09 -0700
commit328141e51e6fc79d21168bfd4e356dddc2ec7491 (patch)
treed96dbb769f25332d17269339873617c350c8f799 /drivers/mmc/host/sdhci-pci-gli.c
parenteff0cb3d91c06acbb957be1134a07afa2c4978e3 (diff)
parent527f36f5efa45b6a897190cabf982e2d207887da (diff)
Merge tag 'mmc-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson: "MMC core: - Add support for the asynchronous SDIO wakeup interrupts - Skip redundant evaluation of eMMC HS400 caps when no-MMC-cap - Add support to store error stats from host drivers - Extend debugfs to show error stats from host drivers - Add single I/O read support in the recovery path for 4k sector cards MMC host: - dw_mmc-exynos: Convert corresponding DT bindings to the dtschema - dw_mmc-rockchip: Add support for the Rockchip RV1126 variant - mmc_spi: Convert corresponding DT bindings to the dtschema - mtk-sd: Extend support for interrupts/pinctrls for SDIO low-power mode - mtk-sd: Add support for SDIO wake irqs - mtk-sd: Add support for the Mediatek MT8188 variant - renesas_sdhi: Drop redundant manual tap correction for newer SoCs - renesas_sdhi: Add support for the R-Car S4-8 and generic Gen4 variants - sdhci/cqhci: Add support to capture stats from host errors - sdhci-brcmstb: Add ability to increase max clock rate for SDIO on 72116b0 - sdhci-msm: Add support for the MSM8998 and SM8450 variant - sdhci-of-at91: Fixup UHS-I mode by rewriting of MC1R - sdhci-of-dwcmshc: Add support for the Rockchip rk3588 variant - sdhci-of-dwcmshc: Enable reset support for the Rockchip variants - sdhci-pci-gli: Improve I/O read/write performance for GL9763E - sdhci-s3c: Convert corresponding DT bindings to the dtschema - tmio: Avoid glitches when resetting MEMSTICK core: - A couple of minor fixes and cleanups" * tag 'mmc-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (61 commits) mmc: mediatek: add support for SDIO eint wakup IRQ mmc: core: Add support for SDIO wakeup interrupt dt-bindings: mmc: mtk-sd: extend interrupts and pinctrls properties dt-bindings: mmc: rockchip-dw-mshc: Document Rockchip RV1126 mmc: renesas_sdhi: newer SoCs don't need manual tap correction mmc: cavium-thunderx: Add of_node_put() when breaking out of loop mmc: cavium-octeon: Add of_node_put() when breaking out of loop mmc: core: quirks: Add of_node_put() when breaking out of loop mmc: sdhci-brcmstb: use clk_get_rate(base_clk) in PM resume dt-bindings: mmc: sdhci-msm: Document the SM8450 compatible mmc: sdhci-msm: drop redundant of_device_id entries dt-bindings: mmc: sdhci-msm: add MSM8998 mmc: block: Add single read for 4k sector cards mmc: mxcmmc: Use mmc_card_sdio macro mmc: core: Use mmc_card_* macro and add a new for the sd_combo type dt-bindings: mmc: sdhci-msm: constrain reg-names per variants dt-bindings: mmc: sdhci-msm: fix reg-names entries dt-bindings: mmc: Add compatible for MediaTek MT8188 dt-bindings: mmc: sdhci-msm: document resets mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R ...
Diffstat (limited to 'drivers/mmc/host/sdhci-pci-gli.c')
-rw-r--r--drivers/mmc/host/sdhci-pci-gli.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c
index f13c08db3da5..4d509f656188 100644
--- a/drivers/mmc/host/sdhci-pci-gli.c
+++ b/drivers/mmc/host/sdhci-pci-gli.c
@@ -95,6 +95,9 @@
#define PCIE_GLI_9763E_SCR 0x8E0
#define GLI_9763E_SCR_AXI_REQ BIT(9)
+#define PCIE_GLI_9763E_CFG 0x8A0
+#define GLI_9763E_CFG_LPSN_DIS BIT(12)
+
#define PCIE_GLI_9763E_CFG2 0x8A4
#define GLI_9763E_CFG2_L1DLY GENMASK(28, 19)
#define GLI_9763E_CFG2_L1DLY_MID 0x54
@@ -963,12 +966,40 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot)
}
#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];
struct sdhci_host *host = slot->host;
u16 clock;
+ /* Enable LPM negotiation to allow entering L1 state */
+ gl9763e_set_low_power_negotiation(slot, true);
+
clock = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
clock &= ~(SDHCI_CLOCK_PLL_EN | SDHCI_CLOCK_CARD_EN);
sdhci_writew(host, clock, SDHCI_CLOCK_CONTROL);
@@ -1002,6 +1033,9 @@ static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip)
clock |= SDHCI_CLOCK_CARD_EN;
sdhci_writew(host, clock, SDHCI_CLOCK_CONTROL);
+ /* Disable LPM negotiation to avoid entering L1 state. */
+ gl9763e_set_low_power_negotiation(slot, false);
+
return 0;
}
#endif