From patchwork Wed May 20 18:06:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean V Kelley X-Patchwork-Id: 11560975 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 68820159A for ; Wed, 20 May 2020 18:07:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5AA8E20671 for ; Wed, 20 May 2020 18:07:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726977AbgETSGz (ORCPT ); Wed, 20 May 2020 14:06:55 -0400 Received: from mga14.intel.com ([192.55.52.115]:46824 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726548AbgETSGq (ORCPT ); Wed, 20 May 2020 14:06:46 -0400 IronPort-SDR: KZu2UvqZH44iNEdPDd+u+w2j5QFYrBQSBcnzKtcty5dhXspVI1mMYw+RPzyDhTZWd+6JLyZ7W2 kai0YI7XL1cA== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 May 2020 11:06:45 -0700 IronPort-SDR: LezuK/BIDnBntPn+DzPG2NCkDGtAklXtxkgwdb0fO07rcWaojInjP3ZCa7ZGVOUZizptkEleJq UnnfbJ5dQX7g== X-IronPort-AV: E=Sophos;i="5.73,414,1583222400"; d="scan'208";a="289442239" Received: from ydandeka-mobl.amr.corp.intel.com (HELO arch-ashland-svkelley.intel.com) ([10.254.5.7]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 May 2020 11:06:45 -0700 From: Sean V Kelley To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, "David E. Box" Subject: [PATCH V3 1/3] PCI: Add defines for Designated Vendor-Specific Capability Date: Wed, 20 May 2020 11:06:38 -0700 Message-Id: <20200520180640.1911202-2-sean.v.kelley@linux.intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200520180640.1911202-1-sean.v.kelley@linux.intel.com> References: <20200520180640.1911202-1-sean.v.kelley@linux.intel.com> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org From: "David E. Box" Add PCIe DVSEC extended capability ID and defines for the header offsets. Defined in PCIe r5.0, sec 7.9.6. Signed-off-by: David E. Box Acked-by: Bjorn Helgaas --- include/uapi/linux/pci_regs.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index f9701410d3b5..09daa9f07b6b 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -720,6 +720,7 @@ #define PCI_EXT_CAP_ID_DPC 0x1D /* Downstream Port Containment */ #define PCI_EXT_CAP_ID_L1SS 0x1E /* L1 PM Substates */ #define PCI_EXT_CAP_ID_PTM 0x1F /* Precision Time Measurement */ +#define PCI_EXT_CAP_ID_DVSEC 0x23 /* Designated Vendor-Specific */ #define PCI_EXT_CAP_ID_DLF 0x25 /* Data Link Feature */ #define PCI_EXT_CAP_ID_PL_16GT 0x26 /* Physical Layer 16.0 GT/s */ #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_16GT @@ -1062,6 +1063,10 @@ #define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */ #define PCI_L1SS_CTL2 0x0c /* Control 2 Register */ +/* Designated Vendor-Specific (DVSEC, PCI_EXT_CAP_ID_DVSEC) */ +#define PCI_DVSEC_HEADER1 0x4 /* Vendor-Specific Header1 */ +#define PCI_DVSEC_HEADER2 0x8 /* Vendor-Specific Header2 */ + /* Data Link Feature */ #define PCI_DLF_CAP 0x04 /* Capabilities Register */ #define PCI_DLF_EXCHANGE_ENABLE 0x80000000 /* Data Link Feature Exchange Enable */ From patchwork Wed May 20 18:06:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean V Kelley X-Patchwork-Id: 11560969 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6F18912 for ; Wed, 20 May 2020 18:06:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B455420708 for ; Wed, 20 May 2020 18:06:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726839AbgETSGr (ORCPT ); Wed, 20 May 2020 14:06:47 -0400 Received: from mga14.intel.com ([192.55.52.115]:46828 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726856AbgETSGr (ORCPT ); Wed, 20 May 2020 14:06:47 -0400 IronPort-SDR: sUQtut9Pzr1VoDTtrHNLBwZ204ImO1RYHyHQB9myqqbklKmP4Cj68dYHEgHk+NyPWICq9tW13/ We57g4IgTByA== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 May 2020 11:06:47 -0700 IronPort-SDR: pks6EnLjyJNCU1GZphB74FZMsu8uIVzb8u0oG0VpjUxQCCzd7SPYSVXii9ekNBFWlsOZtCsIpP WmhFR+oME4kQ== X-IronPort-AV: E=Sophos;i="5.73,414,1583222400"; d="scan'208";a="289442244" Received: from ydandeka-mobl.amr.corp.intel.com (HELO arch-ashland-svkelley.intel.com) ([10.254.5.7]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 May 2020 11:06:46 -0700 From: Sean V Kelley To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Sean V Kelley , Felipe Balbi Subject: [PATCH V3 2/3] PCI: Add basic Compute eXpress Link DVSEC decode Date: Wed, 20 May 2020 11:06:39 -0700 Message-Id: <20200520180640.1911202-3-sean.v.kelley@linux.intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200520180640.1911202-1-sean.v.kelley@linux.intel.com> References: <20200520180640.1911202-1-sean.v.kelley@linux.intel.com> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Compute eXpress Link is a new CPU interconnect created with workload accelerators in mind. The interconnect relies on PCIe Electrical and Physical interconnect for communication. CXL devices enumerate to the OS as an ACPI-described PCIe Root Complex Integrated Endpoint. This patch introduces the bare minimum support by simply looking for and caching the DVSEC CXL Extended Capability. Currently, only CXL.io (which is mandatory to be configured by BIOS) is enabled. In future, we will also add support for CXL.cache and CXL.mem. DocLink: https://www.computeexpresslink.org/ Originally-by: Felipe Balbi Signed-off-by: Sean V Kelley --- drivers/pci/Kconfig | 9 +++++ drivers/pci/Makefile | 1 + drivers/pci/cxl.c | 92 ++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci.h | 7 ++++ drivers/pci/probe.c | 1 + include/linux/pci.h | 3 ++ 6 files changed, 113 insertions(+) create mode 100644 drivers/pci/cxl.c diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 4bef5c2bae9f..eafb200b320b 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -115,6 +115,15 @@ config XEN_PCIDEV_FRONTEND The PCI device frontend driver allows the kernel to import arbitrary PCI devices from a PCI backend to support PCI driver domains. +config PCI_CXL + bool "Enable PCI Compute eXpress Link" + depends on PCI + help + Say Y here if you want the PCI core to detect CXL devices, decode, and + cache the DVSEC CXL Extended Capability as configured by BIOS. + + When in doubt, say N. + config PCI_ATS bool diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 522d2b974e91..465eee31e999 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_PCI_PF_STUB) += pci-pf-stub.o obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_PCI_P2PDMA) += p2pdma.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o +obj-$(CONFIG_PCI_CXL) += cxl.o # Endpoint library must be initialized before its users obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ diff --git a/drivers/pci/cxl.c b/drivers/pci/cxl.c new file mode 100644 index 000000000000..4497c597347f --- /dev/null +++ b/drivers/pci/cxl.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Compute eXpress Link Support + */ + +#include +#include +#include +#include + +#define PCI_DVSEC_VENDOR_ID_CXL 0x1e98 +#define PCI_DVSEC_ID_CXL_DEV 0x0 + +#define PCI_CXL_CAP 0x0a +#define PCI_CXL_CTRL 0x0c +#define PCI_CXL_STS 0x0e +#define PCI_CXL_CTRL2 0x10 +#define PCI_CXL_STS2 0x12 +#define PCI_CXL_LOCK 0x14 + +#define PCI_CXL_CACHE BIT(0) +#define PCI_CXL_IO BIT(1) +#define PCI_CXL_MEM BIT(2) +#define PCI_CXL_HDM_COUNT(reg) (((reg) & (3 << 4)) >> 4) +#define PCI_CXL_VIRAL BIT(14) + +/* + * pci_find_cxl_capability - Identify and return offset to Vendor-Specific + * capabilities. + * + * CXL makes use of Designated Vendor-Specific Extended Capability (DVSEC) + * to uniquely identify both DVSEC Vendor ID and DVSEC ID aligning with + * PCIe r5.0, sec 7.9.6.2 + */ +static int pci_find_cxl_capability(struct pci_dev *dev) +{ + u16 vendor, id; + int pos = 0; + + while ((pos = pci_find_next_ext_capability(dev, pos, + PCI_EXT_CAP_ID_DVSEC))) { + pci_read_config_word(dev, pos + PCI_DVSEC_HEADER1, + &vendor); + pci_read_config_word(dev, pos + PCI_DVSEC_HEADER2, &id); + if (vendor == PCI_DVSEC_VENDOR_ID_CXL && + id == PCI_DVSEC_ID_CXL_DEV) + return pos; + } + + return 0; +} + + +#define FLAG(x, y) (((x) & (y)) ? '+' : '-') + +void pci_cxl_init(struct pci_dev *dev) +{ + u16 cap, ctrl, status, ctrl2, status2, lock; + int cxl; + + /* Only for PCIe */ + if (!pci_is_pcie(dev)) + return; + + /* Only for Device 0 Function 0, Root Complex Integrated Endpoints */ + if (dev->devfn != 0 || (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_END)) + return; + + cxl = pci_find_cxl_capability(dev); + if (!cxl) + return; + + dev->cxl_cap = cxl; + pci_read_config_word(dev, cxl + PCI_CXL_CAP, &cap); + + pci_info(dev, "CXL: Cache%c IO%c Mem%c Viral%c HDMCount %d\n", + FLAG(cap, PCI_CXL_CACHE), + FLAG(cap, PCI_CXL_IO), + FLAG(cap, PCI_CXL_MEM), + FLAG(cap, PCI_CXL_VIRAL), + PCI_CXL_HDM_COUNT(cap)); + + pci_read_config_word(dev, cxl + PCI_CXL_CTRL, &ctrl); + pci_read_config_word(dev, cxl + PCI_CXL_STS, &status); + pci_read_config_word(dev, cxl + PCI_CXL_CTRL2, &ctrl2); + pci_read_config_word(dev, cxl + PCI_CXL_STS2, &status2); + pci_read_config_word(dev, cxl + PCI_CXL_LOCK, &lock); + + pci_info(dev, "CXL: cap ctrl status ctrl2 status2 lock\n"); + pci_info(dev, "CXL: %04x %04x %04x %04x %04x %04x\n", + cap, ctrl, status, ctrl2, status2, lock); +} diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 6d3f75867106..d9905e2dee95 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -469,6 +469,13 @@ static inline void pci_ats_init(struct pci_dev *d) { } static inline void pci_restore_ats_state(struct pci_dev *dev) { } #endif /* CONFIG_PCI_ATS */ +#ifdef CONFIG_PCI_CXL +/* Compute eXpress Link */ +void pci_cxl_init(struct pci_dev *dev); +#else +static inline void pci_cxl_init(struct pci_dev *dev) { } +#endif + #ifdef CONFIG_PCI_PRI void pci_pri_init(struct pci_dev *dev); void pci_restore_pri_state(struct pci_dev *pdev); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 77b8a145c39b..c55df0ae8f06 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2371,6 +2371,7 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_ptm_init(dev); /* Precision Time Measurement */ pci_aer_init(dev); /* Advanced Error Reporting */ pci_dpc_init(dev); /* Downstream Port Containment */ + pci_cxl_init(dev); /* Compute eXpress Link */ pcie_report_downtraining(dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 83ce1cdf5676..9fd544f76447 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -314,6 +314,9 @@ struct pci_dev { #ifdef CONFIG_PCIEAER u16 aer_cap; /* AER capability offset */ struct aer_stats *aer_stats; /* AER stats for this device */ +#endif +#ifdef CONFIG_PCI_CXL + u16 cxl_cap; /* CXL capability offset */ #endif u8 pcie_cap; /* PCIe capability offset */ u8 msi_cap; /* MSI capability offset */ From patchwork Wed May 20 18:06:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean V Kelley X-Patchwork-Id: 11560971 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3705E14B7 for ; Wed, 20 May 2020 18:06:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2946820708 for ; Wed, 20 May 2020 18:06:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726940AbgETSGv (ORCPT ); Wed, 20 May 2020 14:06:51 -0400 Received: from mga14.intel.com ([192.55.52.115]:46831 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726856AbgETSGt (ORCPT ); Wed, 20 May 2020 14:06:49 -0400 IronPort-SDR: 40H4e4sivOBPskR5/hEKzrEX/mKs4VWjbxWNj+bOXl5RJhU+Dppt3ywGtFm/FV+MlYwA+D3JHk HnC6V5sY4TSw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 May 2020 11:06:48 -0700 IronPort-SDR: u9gDP6FZblclJIaNTvy38fhxPFfJMkwzF6VBOKC6I6jaf45Dkik35TYjIPEz9l6IO27V5+BmnD kJhWRiHCVbcQ== X-IronPort-AV: E=Sophos;i="5.73,414,1583222400"; d="scan'208";a="289442253" Received: from ydandeka-mobl.amr.corp.intel.com (HELO arch-ashland-svkelley.intel.com) ([10.254.5.7]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 May 2020 11:06:47 -0700 From: Sean V Kelley To: bhelgaas@google.com Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Sean V Kelley Subject: [PATCH V3 3/3] PCI: Add helpers to enable/disable CXL.mem and CXL.cache Date: Wed, 20 May 2020 11:06:40 -0700 Message-Id: <20200520180640.1911202-4-sean.v.kelley@linux.intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200520180640.1911202-1-sean.v.kelley@linux.intel.com> References: <20200520180640.1911202-1-sean.v.kelley@linux.intel.com> MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org With these helpers, a device driver can enable/disable access to CXL.mem and CXL.cache. Note that the device driver is responsible for managing the memory area. Signed-off-by: Sean V Kelley --- drivers/pci/cxl.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci.h | 8 +++++ 2 files changed, 92 insertions(+) diff --git a/drivers/pci/cxl.c b/drivers/pci/cxl.c index 4497c597347f..e58e5262b59a 100644 --- a/drivers/pci/cxl.c +++ b/drivers/pci/cxl.c @@ -24,6 +24,90 @@ #define PCI_CXL_HDM_COUNT(reg) (((reg) & (3 << 4)) >> 4) #define PCI_CXL_VIRAL BIT(14) +#define PCI_CXL_CONFIG_LOCK BIT(0) + +static void pci_cxl_unlock(struct pci_dev *dev) +{ + int cxl = dev->cxl_cap; + u16 lock; + + pci_read_config_word(dev, cxl + PCI_CXL_LOCK, &lock); + lock &= ~PCI_CXL_CONFIG_LOCK; + pci_write_config_word(dev, cxl + PCI_CXL_LOCK, lock); +} + +static void pci_cxl_lock(struct pci_dev *dev) +{ + int cxl = dev->cxl_cap; + u16 lock; + + pci_read_config_word(dev, cxl + PCI_CXL_LOCK, &lock); + lock |= PCI_CXL_CONFIG_LOCK; + pci_write_config_word(dev, cxl + PCI_CXL_LOCK, lock); +} + +/* + * CXL DVSEC CTRL registers have Read-Write-Lockable attributes. + * PCI_CXL_CONFIG_LOCK locks these CTRL registers by making them RO. + * This lock prevents future changes to configuration and is not intended + * for enforcing mutual exclusion. See CXL 1.1, sec 7.1.1.6 + */ +static int pci_cxl_enable_disable_feature(struct pci_dev *dev, int enable, + u16 feature) +{ + int cxl = dev->cxl_cap; + int ret; + u16 reg; + + if (!dev->cxl_cap) + return -EINVAL; + + /* Only for Device 0 Function 0, Root Complex Integrated Endpoints */ + if (dev->devfn != 0 || (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_END)) + return -EINVAL; + + pci_cxl_unlock(dev); + ret = pci_read_config_word(dev, cxl + PCI_CXL_CTRL, ®); + if (ret) + goto lock; + + if (enable) + reg |= feature; + else + reg &= ~feature; + + ret = pci_write_config_word(dev, cxl + PCI_CXL_CTRL, reg); + +lock: + pci_cxl_lock(dev); + + return ret; +} + +int pci_cxl_mem_enable(struct pci_dev *dev) +{ + return pci_cxl_enable_disable_feature(dev, true, PCI_CXL_MEM); +} +EXPORT_SYMBOL_GPL(pci_cxl_mem_enable); + +void pci_cxl_mem_disable(struct pci_dev *dev) +{ + pci_cxl_enable_disable_feature(dev, false, PCI_CXL_MEM); +} +EXPORT_SYMBOL_GPL(pci_cxl_mem_disable); + +int pci_cxl_cache_enable(struct pci_dev *dev) +{ + return pci_cxl_enable_disable_feature(dev, true, PCI_CXL_CACHE); +} +EXPORT_SYMBOL_GPL(pci_cxl_cache_enable); + +void pci_cxl_cache_disable(struct pci_dev *dev) +{ + pci_cxl_enable_disable_feature(dev, false, PCI_CXL_CACHE); +} +EXPORT_SYMBOL_GPL(pci_cxl_cache_disable); + /* * pci_find_cxl_capability - Identify and return offset to Vendor-Specific * capabilities. diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d9905e2dee95..5ec7fa0eb709 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -472,8 +472,16 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) { } #ifdef CONFIG_PCI_CXL /* Compute eXpress Link */ void pci_cxl_init(struct pci_dev *dev); +int pci_cxl_mem_enable(struct pci_dev *dev); +void pci_cxl_mem_disable(struct pci_dev *dev); +int pci_cxl_cache_enable(struct pci_dev *dev); +void pci_cxl_cache_disable(struct pci_dev *dev); #else static inline void pci_cxl_init(struct pci_dev *dev) { } +static inline int pci_cxl_mem_enable(struct pci_dev *dev) { return 0; } +static inline void pci_cxl_mem_disable(struct pci_dev *dev) { } +static inline int pci_cxl_cache_enable(struct pci_dev *dev) { return 0; } +static inline void pci_cxl_cache_disable(struct pci_dev *dev) { } #endif #ifdef CONFIG_PCI_PRI