Received: by 2002:a25:23cc:0:0:0:0:0 with SMTP id j195csp1256527ybj; Thu, 7 May 2020 19:22:52 -0700 (PDT) X-Google-Smtp-Source: APiQypKuWE3IVGG+R37otLKcSzsxJFvREm6MHM/nxmZzRO9+Y/ZrrLYICHXpuz63RfZAgXv/fEhf X-Received: by 2002:a17:906:695:: with SMTP id u21mr48597ejb.187.1588904572153; Thu, 07 May 2020 19:22:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588904572; cv=none; d=google.com; s=arc-20160816; b=wwukuVDcJ7qQVbBgAwDW8vBJtU9scGVgGYuW3C7Yo1Xl12SPfGb8XtmiKEx8rlVfW9 VkQsn5SeDmTjyF88RzC0rlQJ4Bl+jeZbPMfglT4254b1cZcZVBrtQWySlY2lm8cA14US AdU5QNGHF3ZN21F4cMP7sczE9FZjsX3//L976anxGDL99B0kqrg9dAAhpMt9OvLUA2Yl XLZtLVXSBczGFQiHF0b3K+XiWVl2fjGumjsEY15gflSfCjyAKAt+naX96iknggtG4bvk Jb9DNwT3pWHfS7H1ZhJhvvT0Shhc0bY4aKJkklc36qTjjAN5tfNOCdu4AGfY50unC0BS Ba6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :ironport-sdr:ironport-sdr; bh=YI1OK8c0l8Lr9dZHJzGGf6bb6+OCrQHdLsuGr+2Fglw=; b=GVGURKDnFdFtmTEP+/HWxDkBzGtnQsrA/CUs0ZbKPedAm1E2I11MlvINQeLksjYqgQ BW3XI0H6ADrnnEthyONseyqWjrq26k5gQNpvI9Yans4/rFk9wJVxygjALOdOOQEgs12j VNWplj1bp8kfp9v1XBGJsh9L8cg0Le2Q7fbDFpxMeNO8kWSia4rO4yYm9+gnJCHR9rt0 RsuX0lRMe9wBEUmKZI2bfN2TETiNULfLt/mvomK2vci06qxvdDesLuqku8zfhILj6Fgl BHH9oHi+9u9sKn5Vos4QHRzSGK+1m8lBbY0llY++6EnP1W+glJyq4YF2SHzAZrwPT+Lk IboA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id aq1si148945ejc.344.2020.05.07.19.22.29; Thu, 07 May 2020 19:22:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727803AbgEHCSy (ORCPT + 99 others); Thu, 7 May 2020 22:18:54 -0400 Received: from mga09.intel.com ([134.134.136.24]:50259 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727106AbgEHCSu (ORCPT ); Thu, 7 May 2020 22:18:50 -0400 IronPort-SDR: HfT1icsA+YihydYU9MmBsljDWeNtSCtn6+CowM7e+jHxrJbuqWZ47zi2J32l9myXo0en/Gt4g4 unonD7OCzOMg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 May 2020 19:18:49 -0700 IronPort-SDR: e07gWrxU9+mC3M3e1XBQp4NLcr/ExU4j9m0Lv5duW5oDNQ4FvKHiFeIB0A4Af61thBQ5BgC0NF H6gM77i4ZYlg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,366,1583222400"; d="scan'208";a="407864625" Received: from linux.intel.com ([10.54.29.200]) by orsmga004.jf.intel.com with ESMTP; 07 May 2020 19:18:49 -0700 Received: from debox1-hc.jf.intel.com (debox1-hc.jf.intel.com [10.54.75.159]) by linux.intel.com (Postfix) with ESMTP id 2263558079C; Thu, 7 May 2020 19:18:49 -0700 (PDT) From: "David E. Box" To: bhelgaas@google.com, andy@infradead.org, lee.jones@linaro.org, alexander.h.duyck@linux.intel.com Cc: "David E. Box" , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org Subject: [PATCH v2 2/3] mfd: Intel Platform Monitoring Technology support Date: Thu, 7 May 2020 19:18:43 -0700 Message-Id: <20200508021844.6911-3-david.e.box@linux.intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200505013206.11223-1-david.e.box@linux.intel.com> References: <20200505013206.11223-1-david.e.box@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Intel Platform Monitoring Technology (PMT) is an architecture for enumerating and accessing hardware monitoring facilities. PMT supports multiple types of monitoring capabilities. This driver creates platform devices for each type so that they may be managed by capability specific drivers (to be introduced). Capabilities are discovered using PCIe DVSEC ids. Support is included for the 3 current capability types, Telemetry, Watcher, and Crashlog. The features are available on new Intel platforms starting from Tiger Lake for which support is added. Tiger Lake however will not support Watcher and Crashlog even though the capabilities appear on the device. So add a quirk facility and use it to disable them. Signed-off-by: David E. Box Signed-off-by: Alexander Duyck --- MAINTAINERS | 5 ++ drivers/mfd/Kconfig | 10 +++ drivers/mfd/Makefile | 1 + drivers/mfd/intel_pmt.c | 170 ++++++++++++++++++++++++++++++++++++ include/linux/intel-dvsec.h | 48 ++++++++++ 5 files changed, 234 insertions(+) create mode 100644 drivers/mfd/intel_pmt.c create mode 100644 include/linux/intel-dvsec.h diff --git a/MAINTAINERS b/MAINTAINERS index e64e5db31497..367e49d27960 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8733,6 +8733,11 @@ F: drivers/mfd/intel_soc_pmic* F: include/linux/mfd/intel_msic.h F: include/linux/mfd/intel_soc_pmic* +INTEL PMT DRIVER +M: "David E. Box" +S: Maintained +F: drivers/mfd/intel_pmt.c + INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT M: Stanislav Yakovlev L: linux-wireless@vger.kernel.org diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 0a59249198d3..8777ff99e633 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -632,6 +632,16 @@ config MFD_INTEL_MSIC Passage) chip. This chip embeds audio, battery, GPIO, etc. devices used in Intel Medfield platforms. +config MFD_INTEL_PMT + tristate "Intel Platform Monitoring Technology support" + depends on PCI + select MFD_CORE + help + The Intel Platform Monitoring Technology (PMT) is an interface that + provides access to hardware monitor registers. This driver supports + Telemetry, Watcher, and Crashlog PMT capabilities/devices for + platforms starting from Tiger Lake. + config MFD_IPAQ_MICRO bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support" depends on SA1100_H3100 || SA1100_H3600 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index f935d10cbf0f..0041f673faa1 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -212,6 +212,7 @@ obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o +obj-$(CONFIG_MFD_INTEL_PMT) += intel_pmt.o obj-$(CONFIG_MFD_PALMAS) += palmas.o obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o diff --git a/drivers/mfd/intel_pmt.c b/drivers/mfd/intel_pmt.c new file mode 100644 index 000000000000..951128ec2afa --- /dev/null +++ b/drivers/mfd/intel_pmt.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Platform Monitoring Technology MFD driver + * + * Copyright (c) 2020, Intel Corporation. + * All Rights Reserved. + * + * Authors: David E. Box + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct pmt_platform_info tgl_info = { + .quirks = PMT_QUIRK_NO_WATCHER | PMT_QUIRK_NO_CRASHLOG, +}; + +static int +pmt_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header, + struct pmt_platform_info *info) +{ + struct mfd_cell *cell, *tmp; + const char *name; + int i; + + switch (header->id) { + case DVSEC_INTEL_ID_TELEM: + name = TELEM_DEV_NAME; + break; + case DVSEC_INTEL_ID_WATCHER: + if (info->quirks && PMT_QUIRK_NO_WATCHER) { + dev_info(&pdev->dev, "Watcher not supported\n"); + return 0; + } + name = WATCHER_DEV_NAME; + break; + case DVSEC_INTEL_ID_CRASHLOG: + if (info->quirks && PMT_QUIRK_NO_WATCHER) { + dev_info(&pdev->dev, "Crashlog not supported\n"); + return 0; + } + name = CRASHLOG_DEV_NAME; + break; + default: + return -EINVAL; + } + + cell = devm_kcalloc(&pdev->dev, header->num_entries, + sizeof(*cell), GFP_KERNEL); + if (!cell) + return -ENOMEM; + + /* Create a platform device for each entry. */ + for (i = 0, tmp = cell; i < header->num_entries; i++, tmp++) { + struct resource *res; + + res = devm_kzalloc(&pdev->dev, sizeof(*res), GFP_KERNEL); + if (!res) + return -ENOMEM; + + tmp->name = name; + + res->start = pdev->resource[header->tbir].start + + header->offset + + (i * (INTEL_DVSEC_ENTRY_SIZE << 2)); + res->end = res->start + (header->entry_size << 2) - 1; + res->flags = IORESOURCE_MEM; + + tmp->resources = res; + tmp->num_resources = 1; + tmp->platform_data = header; + tmp->pdata_size = sizeof(*header); + + } + + return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, cell, + header->num_entries, NULL, 0, NULL); +} + +static int +pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + u16 vid; + u32 table; + int ret, pos = 0, last_pos = 0; + struct pmt_platform_info *info; + struct intel_dvsec_header header; + + ret = pcim_enable_device(pdev); + if (ret) + return ret; + + info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info), + GFP_KERNEL); + if (!info) + return -ENOMEM; + + while ((pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC))) { + pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER1, &vid); + if (vid != PCI_VENDOR_ID_INTEL) + continue; + + pci_read_config_word(pdev, pos + PCI_DVSEC_HEADER2, + &header.id); + + pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, + &header.num_entries); + + pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, + &header.entry_size); + + if (!header.num_entries || !header.entry_size) + return -EINVAL; + + pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, + &table); + + header.tbir = INTEL_DVSEC_TABLE_BAR(table); + header.offset = INTEL_DVSEC_TABLE_OFFSET(table); + ret = pmt_add_dev(pdev, &header, info); + if (ret) + dev_warn(&pdev->dev, + "Failed to add devices for DVSEC id %d\n", + header.id); + last_pos = pos; + } + + if (!last_pos) { + dev_err(&pdev->dev, "No supported PMT capabilities found.\n"); + return -ENODEV; + } + + pm_runtime_put(&pdev->dev); + pm_runtime_allow(&pdev->dev); + + return 0; +} + +static void pmt_pci_remove(struct pci_dev *pdev) +{ + pm_runtime_forbid(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); +} + +#define PCI_DEVICE_ID_INTEL_PMT_TGL 0x9a0d + +static const struct pci_device_id pmt_pci_ids[] = { + { PCI_DEVICE_DATA(INTEL, PMT_TGL, &tgl_info) }, + { } +}; +MODULE_DEVICE_TABLE(pci, pmt_pci_ids); + +static struct pci_driver pmt_pci_driver = { + .name = "intel-pmt", + .id_table = pmt_pci_ids, + .probe = pmt_pci_probe, + .remove = pmt_pci_remove, +}; + +module_pci_driver(pmt_pci_driver); + +MODULE_AUTHOR("David E. Box "); +MODULE_DESCRIPTION("Intel Platform Monitoring Technology MFD driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/intel-dvsec.h b/include/linux/intel-dvsec.h new file mode 100644 index 000000000000..87bb67fd62f7 --- /dev/null +++ b/include/linux/intel-dvsec.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef INTEL_DVSEC_H +#define INTEL_DVSEC_H + +#include + +#define DVSEC_INTEL_ID_TELEM 2 +#define DVSEC_INTEL_ID_WATCHER 3 +#define DVSEC_INTEL_ID_CRASHLOG 4 + +#define TELEM_DEV_NAME "pmt_telemetry" +#define WATCHER_DEV_NAME "pmt_watcher" +#define CRASHLOG_DEV_NAME "pmt_crashlog" + +/* Intel DVSEC capability vendor space offsets */ +#define INTEL_DVSEC_ENTRIES 0xA +#define INTEL_DVSEC_SIZE 0xB +#define INTEL_DVSEC_TABLE 0xC +#define INTEL_DVSEC_TABLE_BAR(x) ((x) & GENMASK(2, 0)) +#define INTEL_DVSEC_TABLE_OFFSET(x) ((x) >> 3) + +#define INTEL_DVSEC_ENTRY_SIZE 4 + +/* DVSEC header */ +struct intel_dvsec_header { + u16 length; + u16 id; + u8 num_entries; + u8 entry_size; + u8 entry_max; + u8 tbir; + u32 offset; +}; + +enum pmt_quirks { + /* Watcher capability not supported */ + PMT_QUIRK_NO_WATCHER = (1 << 0), + + /* Crashlog capability not supported */ + PMT_QUIRK_NO_CRASHLOG = (1 << 1), +}; + +struct pmt_platform_info { + unsigned long quirks; + struct intel_dvsec_header **capabilities; +}; + +#endif -- 2.20.1