From: Rajat Jain <rajatja@google.com>
To: Bjorn Helgaas <bhelgaas@google.com>,
Keith Busch <keith.busch@intel.com>,
Andreas Ziegler <andreas.ziegler@fau.de>,
Jonathan Yong <jonathan.yong@intel.com>,
Shawn Lin <shawn.lin@rock-chips.com>,
David Daney <david.daney@cavium.com>,
Julia Lawall <Julia.Lawall@lip6.fr>,
Ram Amrani <Ram.Amrani@cavium.com>,
Doug Ledford <dledford@redhat.com>,
Wang Sheng-Hui <shhuiw@foxmail.com>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Rajat Jain <rajatja@google.com>,
Rajat Jain <rajatxjain@gmail.com>,
Brian Norris <briannorris@google.com>
Subject: [PATCH 4/6] PCI/ASPM: Calculate and save the L1.2 timing parameters
Date: Mon, 2 Jan 2017 22:34:13 -0800 [thread overview]
Message-ID: <1483425255-101923-5-git-send-email-rajatja@google.com> (raw)
In-Reply-To: <1483425255-101923-1-git-send-email-rajatja@google.com>
Calculate and save the timing parameters that need to be programmed
if we need to enable L1.2 substates later.
We use the same logic (and a constant value for 1 of the
parameters) as used by Intel's coreboot:
https://www.coreboot.org/pipermail/coreboot-gerrit/2015-March/021134.html
https://review.coreboot.org/#/c/8832/
Signed-off-by: Rajat Jain <rajatja@google.com>
---
drivers/pci/pcie/aspm.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 7a3ad85..a70afdf 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -42,6 +42,18 @@
#define ASPM_STATE_ALL (ASPM_STATE_L0S | ASPM_STATE_L1 | \
ASPM_STATE_L1SS)
+/*
+ * When L1 substates are enabled, the LTR L1.2 threshold is a timing parameter
+ * that decides whether L1.1 or L1.2 is entered (Refer PCIe spec for details).
+ * Not sure is there is a way to "calculate" this on the fly, but may be we
+ * could turn it into a parameter in future. This value has been taken from
+ * the following files from Intel's coreboot (which is the only code I found
+ * to have used this):
+ * https://www.coreboot.org/pipermail/coreboot-gerrit/2015-March/021134.html
+ * https://review.coreboot.org/#/c/8832/
+ */
+#define LTR_L1_2_THRESHOLD_BITS ((1 << 21) | (1 << 23) | (1 << 30))
+
struct aspm_latency {
u32 l0s; /* L0s latency (nsec) */
u32 l1; /* L1 latency (nsec) */
@@ -76,6 +88,14 @@ struct pcie_link_state {
* has one slot under it, so at most there are 8 functions.
*/
struct aspm_latency acceptable[8];
+
+ /* L1 PM Substate info */
+ struct {
+ u32 up_cap_ptr; /* L1SS cap ptr in upstream dev */
+ u32 dw_cap_ptr; /* L1SS cap ptr in downstream dev */
+ u32 ctl1; /* value to be programmed in ctl1 */
+ u32 ctl2; /* value to be programmed in ctl2 */
+ } l1ss;
};
static int aspm_disabled, aspm_force;
@@ -296,6 +316,22 @@ static u32 calc_l1_acceptable(u32 encoding)
return (1000 << encoding);
}
+/* Convert L1SS T_pwr encoding to usec */
+static u32 calc_l1ss_pwron(struct pci_dev *pdev, u32 scale, u32 val)
+{
+ switch (scale) {
+ case 0:
+ return val * 2;
+ case 1:
+ return val * 10;
+ case 2:
+ return val * 100;
+ }
+ dev_err(&pdev->dev, "%s: Invalid T_PwrOn scale: %u\n",
+ __func__, scale);
+ return 0;
+}
+
struct aspm_register_info {
u32 support:2;
u32 enabled:2;
@@ -392,6 +428,46 @@ static inline struct pci_dev *pci_function_0(struct pci_bus *linkbus)
return NULL;
}
+/* Calculate L1.2 PM substate timing parameters */
+static void aspm_calc_l1ss_info(struct pcie_link_state *link,
+ struct aspm_register_info *upreg,
+ struct aspm_register_info *dwreg)
+{
+ u32 val1, val2, scale1, scale2;
+
+ link->l1ss.up_cap_ptr = upreg->l1ss_cap_ptr;
+ link->l1ss.dw_cap_ptr = dwreg->l1ss_cap_ptr;
+ link->l1ss.ctl1 = link->l1ss.ctl2 = 0;
+
+ if (!(link->aspm_support & ASPM_STATE_L1_2_MASK))
+ return;
+
+ /* Choose the greater of the two T_cmn_mode_rstr_time */
+ val1 = (upreg->l1ss_cap >> 8) & 0xFF;
+ val2 = (upreg->l1ss_cap >> 8) & 0xFF;
+ if (val1 > val2)
+ link->l1ss.ctl1 |= val1 << 8;
+ else
+ link->l1ss.ctl1 |= val2 << 8;
+ /*
+ * We currently use LTR L1.2 threshold to be fixed constant picked from
+ * Intel's coreboot.
+ */
+ link->l1ss.ctl1 |= LTR_L1_2_THRESHOLD_BITS;
+
+ /* Choose the greater of the two T_pwr_on */
+ val1 = (upreg->l1ss_cap >> 19) & 0x1F;
+ scale1 = (upreg->l1ss_cap >> 16) & 0x03;
+ val2 = (dwreg->l1ss_cap >> 19) & 0x1F;
+ scale2 = (dwreg->l1ss_cap >> 16) & 0x03;
+
+ if (calc_l1ss_pwron(link->pdev, scale1, val1) >
+ calc_l1ss_pwron(link->downstream, scale2, val2))
+ link->l1ss.ctl2 |= scale1 | (val1 << 3);
+ else
+ link->l1ss.ctl2 |= scale2 | (val2 << 3);
+}
+
static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
{
struct pci_dev *child, *parent = link->pdev;
@@ -471,6 +547,9 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM;
+ if (link->aspm_support & ASPM_STATE_L1SS)
+ aspm_calc_l1ss_info(link, &upreg, &dwreg);
+
/* Save default state */
link->aspm_default = link->aspm_enabled;
--
2.8.0.rc3.226.g39d4020
next prev parent reply other threads:[~2017-01-03 6:36 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-03 6:34 [PATCH 0/6] PCI/ASPM: Add PCIe L1 PM substate support Rajat Jain
2017-01-03 6:34 ` [PATCH 1/6] PCI: Add L1 substate capability structure register definitions Rajat Jain
2017-01-03 6:34 ` [PATCH 2/6] PCI/ASPM: Introduce L1 substates and a Kconfig for it Rajat Jain
2017-01-03 6:34 ` [PATCH 3/6] PCI/ASPM: Read and setup L1 substate capabilities Rajat Jain
2017-01-03 6:34 ` Rajat Jain [this message]
2017-01-03 6:34 ` [PATCH 5/6] PCI/ASPM: Actually configure the L1 substate settings to the device Rajat Jain
2017-03-08 18:44 ` James Morse
2017-03-08 22:39 ` Bjorn Helgaas
[not found] ` <CACK8Z6H7V=dM71LuUh7653qnLXJmGCNVcm3cG4_s4hwQKe58aA@mail.gmail.com>
2017-03-09 11:00 ` James Morse
2017-01-03 6:34 ` [PATCH 6/6] PCI/ASPM: Add comment about L1 substate latency Rajat Jain
2017-02-14 23:45 ` [PATCH 0/6] PCI/ASPM: Add PCIe L1 PM substate support Bjorn Helgaas
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=1483425255-101923-5-git-send-email-rajatja@google.com \
--to=rajatja@google.com \
--cc=Julia.Lawall@lip6.fr \
--cc=Ram.Amrani@cavium.com \
--cc=andreas.ziegler@fau.de \
--cc=bhelgaas@google.com \
--cc=briannorris@google.com \
--cc=david.daney@cavium.com \
--cc=dledford@redhat.com \
--cc=jonathan.yong@intel.com \
--cc=keith.busch@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=rajatxjain@gmail.com \
--cc=shawn.lin@rock-chips.com \
--cc=shhuiw@foxmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).