From patchwork Sat Nov 20 01:57:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "David E. Box" X-Patchwork-Id: 12629963 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18494C433EF for ; Sat, 20 Nov 2021 01:57:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236254AbhKTCA7 (ORCPT ); Fri, 19 Nov 2021 21:00:59 -0500 Received: from mga01.intel.com ([192.55.52.88]:12659 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233856AbhKTCA7 (ORCPT ); Fri, 19 Nov 2021 21:00:59 -0500 X-IronPort-AV: E=McAfee;i="6200,9189,10173"; a="258318606" X-IronPort-AV: E=Sophos;i="5.87,249,1631602800"; d="scan'208";a="258318606" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2021 17:57:56 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,249,1631602800"; d="scan'208";a="673415486" Received: from linux.intel.com ([10.54.29.200]) by orsmga005.jf.intel.com with ESMTP; 19 Nov 2021 17:57:56 -0800 Received: from debox1-server.jf.intel.com (debox1-server.jf.intel.com [10.54.39.121]) by linux.intel.com (Postfix) with ESMTP id 9BD75580945; Fri, 19 Nov 2021 17:57:56 -0800 (PST) From: "David E. Box" To: nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev, lorenzo.pieralisi@arm.com, robh@kernel.org, kw@linux.com, bhelgaas@google.com, david.e.box@linux.intel.com, michael.a.bottini@linux.intel.com, rafael@kernel.org Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] PCI/ASPM: Add ASPM BIOS override function Date: Fri, 19 Nov 2021 17:57:55 -0800 Message-Id: <20211120015756.1396263-1-david.e.box@linux.intel.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Michael Bottini Devices that appear under the Intel VMD host bridge are not visible to BIOS and therefore not programmed by BIOS with ASPM settings. For these devices, it is necessary for the driver to configure ASPM. Since ASPM settings are adjustable at runtime by module parameter, use the same mechanism to allow drivers to override the default (in this case never configured) BIOS policy to ASPM_STATE_ALL. Then, reconfigure ASPM on the link. Signed-off-by: Michael Bottini Signed-off-by: David E. Box --- drivers/pci/pci.h | 2 ++ drivers/pci/pcie/aspm.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 3d60cabde1a1..172ec914e988 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -562,11 +562,13 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev); void pcie_aspm_exit_link_state(struct pci_dev *pdev); void pcie_aspm_pm_state_change(struct pci_dev *pdev); void pcie_aspm_powersave_config_link(struct pci_dev *pdev); +void pcie_aspm_policy_override(struct pci_dev *dev); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { } static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { } static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } +static inline void pcie_aspm_policy_override(struct pci_dev *dev) {} #endif #ifdef CONFIG_PCIE_ECRC diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 52c74682601a..ccb98586bf0d 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -1140,6 +1140,24 @@ int pci_disable_link_state(struct pci_dev *pdev, int state) } EXPORT_SYMBOL(pci_disable_link_state); +void pcie_aspm_policy_override(struct pci_dev *pdev) +{ + struct pcie_link_state *link = pcie_aspm_get_link(pdev); + + down_read(&pci_bus_sem); + mutex_lock(&aspm_lock); + + if (link) { + link->aspm_default = ASPM_STATE_ALL; + pcie_config_aspm_link(link, policy_to_aspm_state(link)); + pcie_set_clkpm(link, policy_to_clkpm_state(link)); + } + + mutex_unlock(&aspm_lock); + up_read(&pci_bus_sem); +} +EXPORT_SYMBOL(pcie_aspm_policy_override); + static int pcie_aspm_set_policy(const char *val, const struct kernel_param *kp) { From patchwork Sat Nov 20 01:57:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "David E. Box" X-Patchwork-Id: 12629965 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3364C433F5 for ; Sat, 20 Nov 2021 01:57:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236274AbhKTCBA (ORCPT ); Fri, 19 Nov 2021 21:01:00 -0500 Received: from mga05.intel.com ([192.55.52.43]:42362 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236252AbhKTCA7 (ORCPT ); Fri, 19 Nov 2021 21:00:59 -0500 X-IronPort-AV: E=McAfee;i="6200,9189,10173"; a="320741100" X-IronPort-AV: E=Sophos;i="5.87,249,1631602800"; d="scan'208";a="320741100" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Nov 2021 17:57:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,249,1631602800"; d="scan'208";a="551344448" Received: from linux.intel.com ([10.54.29.200]) by fmsmga008.fm.intel.com with ESMTP; 19 Nov 2021 17:57:56 -0800 Received: from debox1-server.jf.intel.com (debox1-server.jf.intel.com [10.54.39.121]) by linux.intel.com (Postfix) with ESMTP id 9E78E580A8B; Fri, 19 Nov 2021 17:57:56 -0800 (PST) From: "David E. Box" To: nirmal.patel@linux.intel.com, jonathan.derrick@linux.dev, lorenzo.pieralisi@arm.com, robh@kernel.org, kw@linux.com, bhelgaas@google.com, david.e.box@linux.intel.com, michael.a.bottini@linux.intel.com, rafael@kernel.org Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] PCI: vmd: Override ASPM on TGL/ADL VMD devices Date: Fri, 19 Nov 2021 17:57:56 -0800 Message-Id: <20211120015756.1396263-2-david.e.box@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211120015756.1396263-1-david.e.box@linux.intel.com> References: <20211120015756.1396263-1-david.e.box@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: Michael Bottini On Tiger Lake and Alder Lake platforms, VMD controllers do not have ASPM enabled nor LTR values set by BIOS. This leads high power consumption on these platforms when VMD is enabled as reported in bugzilla [1]. Enable these features in the VMD driver using pcie_aspm_policy_override() to set the ASPM policy for the root ports. To do this, add an additional flag in VMD features to specify devices that must have their respective policies overridden. [1] https://bugzilla.kernel.org/show_bug.cgi?id=213717 Signed-off-by: Michael Bottini Signed-off-by: David E. Box Reported-by: kernel test robot Reported-by: kernel test robot --- drivers/pci/controller/vmd.c | 40 +++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index a45e8e59d3d4..0d0b8888cd90 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -20,6 +20,8 @@ #include +#include "../pci.h" + #define VMD_CFGBAR 0 #define VMD_MEMBAR1 2 #define VMD_MEMBAR2 4 @@ -67,6 +69,12 @@ enum vmd_features { * interrupt handling. */ VMD_FEAT_CAN_BYPASS_MSI_REMAP = (1 << 4), + + /* + * Device must have ASPM policy overridden, as its default policy is + * incorrect. + */ + VMD_FEAT_QUIRK_OVERRIDE_ASPM = (1 << 5), }; static DEFINE_IDA(vmd_instance_ida); @@ -661,6 +669,27 @@ static int vmd_alloc_irqs(struct vmd_dev *vmd) return 0; } +/* + * Override the BIOS ASPM policy and set the LTR value for PCI storage + * devices on the VMD bride. + */ +int vmd_enable_aspm(struct pci_dev *pdev, void *userdata) +{ + int features = *(int *)userdata; + + if (features & VMD_FEAT_QUIRK_OVERRIDE_ASPM && + pdev->class == PCI_CLASS_STORAGE_EXPRESS) { + int pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR); + + if (pos) { + pci_write_config_word(pdev, pos + PCI_LTR_MAX_SNOOP_LAT, 0x1003); + pci_write_config_word(pdev, pos + PCI_LTR_MAX_NOSNOOP_LAT, 0x1003); + pcie_aspm_policy_override(pdev); + } + } + return 0; +} + static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) { struct pci_sysdata *sd = &vmd->sysdata; @@ -807,6 +836,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) pci_scan_child_bus(vmd->bus); pci_assign_unassigned_bus_resources(vmd->bus); + pci_walk_bus(vmd->bus, vmd_enable_aspm, &features); + /* * VMD root buses are virtual and don't return true on pci_is_pcie() * and will fail pcie_bus_configure_settings() early. It can instead be @@ -948,15 +979,18 @@ static const struct pci_device_id vmd_ids[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x467f), .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | VMD_FEAT_HAS_BUS_RESTRICTIONS | - VMD_FEAT_OFFSET_FIRST_VECTOR,}, + VMD_FEAT_OFFSET_FIRST_VECTOR | + VMD_FEAT_QUIRK_OVERRIDE_ASPM,}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c3d), .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | VMD_FEAT_HAS_BUS_RESTRICTIONS | - VMD_FEAT_OFFSET_FIRST_VECTOR,}, + VMD_FEAT_OFFSET_FIRST_VECTOR | + VMD_FEAT_QUIRK_OVERRIDE_ASPM,}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VMD_9A0B), .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP | VMD_FEAT_HAS_BUS_RESTRICTIONS | - VMD_FEAT_OFFSET_FIRST_VECTOR,}, + VMD_FEAT_OFFSET_FIRST_VECTOR | + VMD_FEAT_QUIRK_OVERRIDE_ASPM,}, {0,} }; MODULE_DEVICE_TABLE(pci, vmd_ids);