Received: by 2002:a25:f815:0:0:0:0:0 with SMTP id u21csp1326749ybd; Wed, 26 Jun 2019 15:39:42 -0700 (PDT) X-Google-Smtp-Source: APXvYqwWu+HHhPfpO4yfYAxrwSkouH0FNsOO33kwEy0yyMq0MKPd8DwaGzkZz9/bm/5muOSPoMPR X-Received: by 2002:a17:90a:214f:: with SMTP id a73mr1762463pje.21.1561588781956; Wed, 26 Jun 2019 15:39:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561588781; cv=none; d=google.com; s=arc-20160816; b=0ymVptLYlFqvRQYhKQbUhnWJyri4GEN6mmqtOS6KZ5I88OriK3pqYCZ2zPcB7S5PNM USEK3t94jrjq3ALpKA4dcXb4kYqJgQPTbCMUvKyXyhaDronnBNrpPQyHp3uxKzkeVNAw 93C/THVN5/G1pXZgPYPvi1oDr6NokFVI+GMqERiYzS15aBuleRVykpy7E+ZTp9HVbTsX uhSEu1kN08LAK3+S1eR/1MktPvW4b9qDDOUpqHrOmaPa/Nj7IORuFzfiyjVnIF8yIVBL IEcM7+wjA6nwVblv2ijJp+wakSJSF+qWpRCEazmGVtjYyh1msgTpYb59RZZCTz4vakD/ d7Sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=z9KGsr/7RIWfpWgmqODe5pmubSSMMnR+CcME/Fo1dyc=; b=t7LRn8r3hwyFrBAMdfVE9To19CvliLqmh55tsanKYmJjBCHjIGUMjP0zOFTRMUA75B MkvqbpAbdt5nozzHBiDPfAmst+fyifPJ9aHB3kQ3fR2hT0owtUYDIfCsSGyN7rBkkyxY z6QBbnEa4tG4huWwPKVTH7Y2BZh9WsbCtH9L2QRmhMl4YfV/iY6vCrgIfQM+F1cmkoHX gV9rgS2UwtygKiKETQW9Dp9U9QJ2+LmvEx06PNI2jcHJUv5vw9l/EUKOaGDg36F1QXvM IYLkTu9v2DPBO8kM/fASxKJSN8fktSXyvYHmGYC5CWglIfuX2soC/NUV3l890AD42bgr b8uw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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. [209.132.180.67]) by mx.google.com with ESMTP id d18si354367pls.423.2019.06.26.15.39.25; Wed, 26 Jun 2019 15:39:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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 S1726668AbfFZWjL (ORCPT + 99 others); Wed, 26 Jun 2019 18:39:11 -0400 Received: from mga11.intel.com ([192.55.52.93]:10648 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726606AbfFZWjF (ORCPT ); Wed, 26 Jun 2019 18:39:05 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Jun 2019 15:39:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,421,1557212400"; d="scan'208";a="313575009" Received: from spandruv-mobl.amr.corp.intel.com ([10.251.133.109]) by orsmga004.jf.intel.com with ESMTP; 26 Jun 2019 15:39:03 -0700 From: Srinivas Pandruvada To: dvhart@infradead.org, andy@infradead.org, andriy.shevchenko@intel.com, corbet@lwn.net Cc: rjw@rjwysocki.net, alan@linux.intel.com, lenb@kernel.org, prarit@redhat.com, darcari@redhat.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org, Srinivas Pandruvada Subject: [PATCH 07/10] platform/x86: ISST: Add Intel Speed Select mailbox interface via MSRs Date: Wed, 26 Jun 2019 15:38:48 -0700 Message-Id: <20190626223851.19138-8-srinivas.pandruvada@linux.intel.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190626223851.19138-1-srinivas.pandruvada@linux.intel.com> References: <20190626223851.19138-1-srinivas.pandruvada@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add an IOCTL to send mailbox commands to PUNIT using PUNIT MSRs for mailbox. Some CPU models don't have PCI device, so need to use MSRs. A limited set of mailbox commands can be sent to PUNIT. This MMIO interface is used by the intel-speed-select tool under tools/x86/power to enumerate and control Intel Speed Select features. The MBOX commands ids and semantics of the message can be checked from the source code of the tool. Signed-off-by: Srinivas Pandruvada --- .../x86/intel_speed_select_if/Makefile | 1 + .../intel_speed_select_if/isst_if_mbox_msr.c | 180 ++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 drivers/platform/x86/intel_speed_select_if/isst_if_mbox_msr.c diff --git a/drivers/platform/x86/intel_speed_select_if/Makefile b/drivers/platform/x86/intel_speed_select_if/Makefile index 8dec8c858649..856076206f35 100644 --- a/drivers/platform/x86/intel_speed_select_if/Makefile +++ b/drivers/platform/x86/intel_speed_select_if/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += isst_if_common.o obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += isst_if_mmio.o obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += isst_if_mbox_pci.o +obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += isst_if_mbox_msr.o diff --git a/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_msr.c b/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_msr.c new file mode 100644 index 000000000000..a949ec436c73 --- /dev/null +++ b/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_msr.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Speed Select Interface: Mbox via MSR Interface + * Copyright (c) 2019, Intel Corporation. + * All rights reserved. + * + * Author: Srinivas Pandruvada + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "isst_if_common.h" + +#define MSR_OS_MAILBOX_INTERFACE 0xB0 +#define MSR_OS_MAILBOX_DATA 0xB1 +#define MSR_OS_MAILBOX_BUSY_BIT 31 + +/* + * Based on experiments count is never more than 1, as the MSR overhead + * is enough to finish the command. So here this is the worst case number. + */ +#define OS_MAILBOX_RETRY_COUNT 3 + +static int isst_if_send_mbox_cmd(u8 command, u8 sub_command, u32 parameter, + u32 command_data, u32 *response_data) +{ + u32 retries; + u64 data; + int ret; + + /* Poll for rb bit == 0 */ + retries = OS_MAILBOX_RETRY_COUNT; + do { + rdmsrl(MSR_OS_MAILBOX_INTERFACE, data); + if (data & BIT_ULL(MSR_OS_MAILBOX_BUSY_BIT)) { + ret = -EBUSY; + continue; + } + ret = 0; + break; + } while (--retries); + + if (ret) + return ret; + + /* Write DATA register */ + wrmsrl(MSR_OS_MAILBOX_DATA, command_data); + + /* Write command register */ + data = BIT_ULL(MSR_OS_MAILBOX_BUSY_BIT) | + (parameter & GENMASK_ULL(13, 0)) << 16 | + (sub_command << 8) | + command; + wrmsrl(MSR_OS_MAILBOX_INTERFACE, data); + + /* Poll for rb bit == 0 */ + retries = OS_MAILBOX_RETRY_COUNT; + do { + rdmsrl(MSR_OS_MAILBOX_INTERFACE, data); + if (data & BIT_ULL(MSR_OS_MAILBOX_BUSY_BIT)) { + ret = -EBUSY; + continue; + } + + if (data & 0xff) + return -ENXIO; + + if (response_data) { + rdmsrl(MSR_OS_MAILBOX_DATA, data); + *response_data = data; + } + ret = 0; + break; + } while (--retries); + + return ret; +} + +struct msrl_action { + int err; + struct isst_if_mbox_cmd *mbox_cmd; +}; + +/* revisit, smp_call_function_single should be enough for atomic mailbox! */ +static void msrl_update_func(void *info) +{ + struct msrl_action *act = info; + + act->err = isst_if_send_mbox_cmd(act->mbox_cmd->command, + act->mbox_cmd->sub_command, + act->mbox_cmd->parameter, + act->mbox_cmd->req_data, + &act->mbox_cmd->resp_data); +} + +static long isst_if_mbox_proc_cmd(u8 *cmd_ptr, int *write_only, int resume) +{ + struct msrl_action action; + int ret; + + action.mbox_cmd = (struct isst_if_mbox_cmd *)cmd_ptr; + + if (isst_if_mbox_cmd_invalid(action.mbox_cmd)) + return -EINVAL; + + if (isst_if_mbox_cmd_set_req(action.mbox_cmd) && + !capable(CAP_SYS_ADMIN)) + return -EPERM; + + /* + * To complete mailbox command, we need to access two MSRs. + * So we don't want race to complete a mailbox transcation. + * Here smp_call ensures that msrl_update_func() has no race + * and also with wait flag, wait for completion. + * smp_call_function_single is using get_cpu() and put_cpu(). + */ + ret = smp_call_function_single(action.mbox_cmd->logical_cpu, + msrl_update_func, &action, 1); + if (ret) + return ret; + + *write_only = 0; + + return action.err; +} + +#define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, } + +static const struct x86_cpu_id isst_if_cpu_ids[] = { + ICPU(INTEL_FAM6_SKYLAKE_X), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, isst_if_cpu_ids); + +static int __init isst_if_mbox_init(void) +{ + struct isst_if_cmd_cb cb; + const struct x86_cpu_id *id; + u64 data; + int ret; + + id = x86_match_cpu(isst_if_cpu_ids); + if (!id) + return -ENODEV; + + /* Check presence of mailbox MSRs */ + ret = rdmsrl_safe(MSR_OS_MAILBOX_INTERFACE, &data); + if (ret) + return ret; + + ret = rdmsrl_safe(MSR_OS_MAILBOX_DATA, &data); + if (ret) + return ret; + + memset(&cb, 0, sizeof(cb)); + cb.cmd_size = sizeof(struct isst_if_mbox_cmd); + cb.offset = offsetof(struct isst_if_mbox_cmds, mbox_cmd); + cb.cmd_callback = isst_if_mbox_proc_cmd; + cb.owner = THIS_MODULE; + return isst_if_cdev_register(ISST_IF_DEV_MBOX, &cb); +} +module_init(isst_if_mbox_init) + +static void __exit isst_if_mbox_exit(void) +{ + isst_if_cdev_unregister(ISST_IF_DEV_MBOX); +} +module_exit(isst_if_mbox_exit) + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Intel speed select interface mailbox driver"); -- 2.17.2