All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kai-Heng Feng <kai.heng.feng@canonical.com>
To: bhelgaas@google.com, jonathan.derrick@intel.com
Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	Chris Packham <chris.packham@alliedtelesis.co.nz>,
	Yicong Yang <yangyicong@hisilicon.com>,
	linux-pci@vger.kernel.org (open list:PCI SUBSYSTEM),
	linux-kernel@vger.kernel.org (open list)
Subject: [PATCH 1/2] PCI/ASPM: Add helper to enable ASPM link
Date: Wed, 30 Sep 2020 16:24:53 +0800	[thread overview]
Message-ID: <20200930082455.25613-1-kai.heng.feng@canonical.com> (raw)

Platform firmware may not be able to access config space to program
ASPM. For instance, devices behind Intel VMD are not configured by the
BIOS.

So add a helper to let drivers have an option to enable ASPM.

Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
---
 drivers/pci/pcie/aspm.c | 73 ++++++++++++++++++++++++++++++-----------
 include/linux/pci.h     |  7 ++++
 2 files changed, 60 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 253c30cc1967..b5ac6a99e016 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -1080,6 +1080,58 @@ static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev)
 	return bridge->link_state;
 }
 
+static u32 pcie_aspm_convert_state(int state)
+{
+	u32 aspm = 0;
+
+	if (state & PCIE_LINK_STATE_L0S)
+		aspm |= ASPM_STATE_L0S;
+	if (state & PCIE_LINK_STATE_L1)
+		/* L1 PM substates require L1 */
+		aspm |= ASPM_STATE_L1 | ASPM_STATE_L1SS;
+	if (state & PCIE_LINK_STATE_L1_1)
+		aspm |= ASPM_STATE_L1_1;
+	if (state & PCIE_LINK_STATE_L1_2)
+		aspm |= ASPM_STATE_L1_2;
+	if (state & PCIE_LINK_STATE_L1_1_PCIPM)
+		aspm |= ASPM_STATE_L1_1_PCIPM;
+	if (state & PCIE_LINK_STATE_L1_2_PCIPM)
+		aspm |= ASPM_STATE_L1_2_PCIPM;
+
+	return aspm;
+}
+
+static void pci_set_link_state(struct pci_dev *pdev, bool enable, int state)
+{
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
+
+	mutex_lock(&aspm_lock);
+	if (enable)
+		link->aspm_default = pcie_aspm_convert_state(state);
+	else
+		link->aspm_disable = pcie_aspm_convert_state(state);
+	pcie_config_aspm_link(link, policy_to_aspm_state(link));
+
+	if (state & PCIE_LINK_STATE_CLKPM) {
+		link->clkpm_default = enable;
+		link->clkpm_disable = !enable;
+	}
+	pcie_set_clkpm(link, policy_to_clkpm_state(link));
+	mutex_unlock(&aspm_lock);
+}
+
+int pci_enable_link_state(struct pci_dev *pdev, int state)
+{
+	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
+
+	if (!link)
+		return -EINVAL;
+
+	pci_set_link_state(pdev, true, state);
+	return 0;
+}
+EXPORT_SYMBOL(pci_enable_link_state);
+
 static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 {
 	struct pcie_link_state *link = pcie_aspm_get_link(pdev);
@@ -1101,26 +1153,7 @@ static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 
 	if (sem)
 		down_read(&pci_bus_sem);
-	mutex_lock(&aspm_lock);
-	if (state & PCIE_LINK_STATE_L0S)
-		link->aspm_disable |= ASPM_STATE_L0S;
-	if (state & PCIE_LINK_STATE_L1)
-		/* L1 PM substates require L1 */
-		link->aspm_disable |= ASPM_STATE_L1 | ASPM_STATE_L1SS;
-	if (state & PCIE_LINK_STATE_L1_1)
-		link->aspm_disable |= ASPM_STATE_L1_1;
-	if (state & PCIE_LINK_STATE_L1_2)
-		link->aspm_disable |= ASPM_STATE_L1_2;
-	if (state & PCIE_LINK_STATE_L1_1_PCIPM)
-		link->aspm_disable |= ASPM_STATE_L1_1_PCIPM;
-	if (state & PCIE_LINK_STATE_L1_2_PCIPM)
-		link->aspm_disable |= ASPM_STATE_L1_2_PCIPM;
-	pcie_config_aspm_link(link, policy_to_aspm_state(link));
-
-	if (state & PCIE_LINK_STATE_CLKPM)
-		link->clkpm_disable = 1;
-	pcie_set_clkpm(link, policy_to_clkpm_state(link));
-	mutex_unlock(&aspm_lock);
+	pci_set_link_state(pdev, false, state);
 	if (sem)
 		up_read(&pci_bus_sem);
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 835530605c0d..a6a7830ec258 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1568,14 +1568,21 @@ extern bool pcie_ports_native;
 #define PCIE_LINK_STATE_L1_2		BIT(4)
 #define PCIE_LINK_STATE_L1_1_PCIPM	BIT(5)
 #define PCIE_LINK_STATE_L1_2_PCIPM	BIT(6)
+#define PCIE_LINK_STATE_ALL		(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |\
+					 PCIE_LINK_STATE_CLKPM | PCIE_LINK_STATE_L1_1 |\
+					 PCIE_LINK_STATE_L1_2 | PCIE_LINK_STATE_L1_1_PCIPM |\
+					 PCIE_LINK_STATE_L1_2_PCIPM)
 
 #ifdef CONFIG_PCIEASPM
+int pci_enable_link_state(struct pci_dev *pdev, int state);
 int pci_disable_link_state(struct pci_dev *pdev, int state);
 int pci_disable_link_state_locked(struct pci_dev *pdev, int state);
 void pcie_no_aspm(void);
 bool pcie_aspm_support_enabled(void);
 bool pcie_aspm_enabled(struct pci_dev *pdev);
 #else
+static inline int pci_enable_link_state(struct pci_dev *pdev, int state)
+{ return 0; }
 static inline int pci_disable_link_state(struct pci_dev *pdev, int state)
 { return 0; }
 static inline int pci_disable_link_state_locked(struct pci_dev *pdev, int state)
-- 
2.17.1


             reply	other threads:[~2020-09-30  8:25 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-30  8:24 Kai-Heng Feng [this message]
2020-09-30  8:24 ` [PATCH 2/2] PCI: vmd: Enable ASPM for mobile platforms Kai-Heng Feng
2020-10-02 22:18   ` Bjorn Helgaas
2020-10-05 18:40     ` Kai-Heng Feng
2020-10-05 19:19       ` Bjorn Helgaas
2020-10-07  4:26         ` Kai-Heng Feng
2020-10-07  9:28           ` Ian Kumlien
2020-10-07 13:30           ` Bjorn Helgaas
2020-10-07 13:44             ` Ian Kumlien
2020-10-08  4:19             ` Kai-Heng Feng
2020-10-09 14:34               ` Ian Kumlien

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=20200930082455.25613-1-kai.heng.feng@canonical.com \
    --to=kai.heng.feng@canonical.com \
    --cc=bhelgaas@google.com \
    --cc=chris.packham@alliedtelesis.co.nz \
    --cc=hkallweit1@gmail.com \
    --cc=jonathan.derrick@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=yangyicong@hisilicon.com \
    /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.