From patchwork Tue Jan 3 06:34:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajat Jain X-Patchwork-Id: 9494453 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 35FC5606B4 for ; Tue, 3 Jan 2017 06:35:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 298E82015F for ; Tue, 3 Jan 2017 06:35:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1DDED26861; Tue, 3 Jan 2017 06:35:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9AB65266F3 for ; Tue, 3 Jan 2017 06:35:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934535AbdACGfp (ORCPT ); Tue, 3 Jan 2017 01:35:45 -0500 Received: from mail-pf0-f181.google.com ([209.85.192.181]:35481 "EHLO mail-pf0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934544AbdACGeo (ORCPT ); Tue, 3 Jan 2017 01:34:44 -0500 Received: by mail-pf0-f181.google.com with SMTP id i88so75343340pfk.2 for ; Mon, 02 Jan 2017 22:34:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ebIRHTyGtAy39YGu25v+X8VgLeqblfz2NQ1SxI9pYeU=; b=ibA0Ig8aB/O3zihein/lJtTPMddsyfG1pgp5Ioc6Xc+pGUwXrgOzjsmkTEp7J7OFxE tHECKbyw21ROV4+7TTP2iuTGHcgyvIx3yRM0D48IGIkwAPeyM8IuKDv2SZqY6tiq/130 AlKgakuYAwbaPsyMwXmaAuCaXFxgrV7ZxE8bJB9B3tn55KpZGX8L0XVvEs1eH9HDCop2 gLbeBKqIUywY3eQVCK33QLiBXcQOCd8o3OaaFdR1Uhe6hzHCKTy3YqZHYOtZcZYzXqA6 KFxYTNw9tpSKJXNSlVcErWD7AovRrsMjGDQDgk104g2anO3uTAUdD1vIv/7JirTYpAS4 wa4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ebIRHTyGtAy39YGu25v+X8VgLeqblfz2NQ1SxI9pYeU=; b=l3Xt5BilUftwqMdhtmA5v+FB9t1nVXQAEPF7i+jNC7jtV5Mk8Das0UuM8WwVK+ta60 MYfuAIvTQElP6730ZVBkRZjMhWBTzumKA5XTzHSmqaAaOCfsUAzuatWt5nP2jGwch3GO rato43Q2hKcUjKOYDDJILpojHz47HlR1kDVUD29ZUPHsI2beHSiLlwLDGTVdYBNwEiMs m7jti78qDy6lWuP6VERItUJOza1wtCxtgE4uyK0Uv8DSbAXIVH3q26DPd64C4C0VM7YA wnV0VqG/kU1TWst00tWw9V3+42Kd1tsyLdTeVCo0VL1gRqppCUfWpWOlzTkPXYeJvFE7 HdDw== X-Gm-Message-State: AIkVDXLkH5CoYUsXixvWYitJwCywft2RWENSribRho0KkoWVX98FyFf9UpUl/5+TURZe4J6u X-Received: by 10.84.215.130 with SMTP id l2mr122773805pli.121.1483425277234; Mon, 02 Jan 2017 22:34:37 -0800 (PST) Received: from rajat.mtv.corp.google.com ([172.22.64.13]) by smtp.gmail.com with ESMTPSA id g28sm72936251pgn.13.2017.01.02.22.34.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 02 Jan 2017 22:34:36 -0800 (PST) From: Rajat Jain To: Bjorn Helgaas , Keith Busch , Andreas Ziegler , Jonathan Yong , Shawn Lin , David Daney , Julia Lawall , Ram Amrani , Doug Ledford , Wang Sheng-Hui , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Rajat Jain , Rajat Jain , Brian Norris Subject: [PATCH 4/6] PCI/ASPM: Calculate and save the L1.2 timing parameters Date: Mon, 2 Jan 2017 22:34:13 -0800 Message-Id: <1483425255-101923-5-git-send-email-rajatja@google.com> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1483425255-101923-1-git-send-email-rajatja@google.com> References: <1483425255-101923-1-git-send-email-rajatja@google.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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;