From patchwork Fri Sep 15 17:28:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shiju Jose X-Patchwork-Id: 140575 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp1211596vqi; Fri, 15 Sep 2023 10:33:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHGSJlNbJqCK0xnAff/c1rFLSrgTuQblkhKILZbG1XoYSdG+96KvVD7/fWCUtkAg+nvQx72 X-Received: by 2002:a05:6a00:2451:b0:68a:5cf8:dae4 with SMTP id d17-20020a056a00245100b0068a5cf8dae4mr3276654pfj.3.1694799238244; Fri, 15 Sep 2023 10:33:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694799238; cv=none; d=google.com; s=arc-20160816; b=b8zDtUk+MSbzNEd+sQpslkMx5kxIb/r5qt8kM9RwzUfXvMk6d90I2wTx4hqlF3HRgD U+Qn5rox/5O78JZGPS79kOZKjO4HvnGv6C7x+GIzpoKjGGGOYC5CyaLP16g7na2i7e4B XKDndgMUSo+env6STmpwMLsL5bpvb1xR2VmlWVT2DLtIbCYza1zfj0QnQcgM0ppdDhxA xH/nz0CRJpvfFLW26BIF61t+hZN5DImJ3XN5ZoiOAMVXsSMwkB6WkDwjWmq/oo3WKg1C InpEeIuCXojKGR4qM5pk81TRqqTTUoNBDrD5nDB5d8BB1BOlrAsmt9u7jaQH5h/6rzET LY6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=FHAU3zMpaz6YfNbIxl84w6JNtmNTEhNBeSn1h4RlwOo=; fh=WKBpDtHuHnn7rxy87+LpIKVTV/YGZSowSVhS84rRWDg=; b=jkUT5+0VqsOWdROvYa8g0BXiKea2lTbtqSBPYnL42adPeyqdYJcquHI1CQ57KlQMq6 hJSD3HqVg0pSlRbACK1mUflgmWpnYoYy8F/BqctLsZBUGDAoyt007VSL0PrPMVLIKw89 0UcfbTXJE+NoOAq1WKkLCwxdpllFTOP+BLGOfOqxGPbrMb0Idu2FbTkihi2695p6J+re hHZ8O17OB6+cDiVcXFy049ZbW2N6XwsGMpXAv6Pa2ZSQgl53lAAQ61BKIoLhs7E1Z+m+ I/FkdPyEkrH4vgMhlSM5WweHQg3xiYbFRJ3AwSzhAv2Zgkovdpw1GJD7tLqIbgjPJI3j WtFQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id ct24-20020a056a000f9800b0068fb4842092si3612672pfb.183.2023.09.15.10.33.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 10:33:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id E5B64807C75F; Fri, 15 Sep 2023 10:30:20 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236399AbjIOR3y (ORCPT + 30 others); Fri, 15 Sep 2023 13:29:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236057AbjIOR3O (ORCPT ); Fri, 15 Sep 2023 13:29:14 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 404F72111; Fri, 15 Sep 2023 10:29:08 -0700 (PDT) Received: from lhrpeml500006.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RnLdz49S5z67nH3; Sat, 16 Sep 2023 01:24:23 +0800 (CST) Received: from SecurePC30232.china.huawei.com (10.122.247.234) by lhrpeml500006.china.huawei.com (7.191.161.198) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Fri, 15 Sep 2023 18:29:06 +0100 From: To: , , CC: , , , , , , , , , , , , , , , , , , , , , Subject: [RFC PATCH 5/9] ACPI:RASF: Add common library for RASF and RAS2 PCC interfaces Date: Sat, 16 Sep 2023 01:28:14 +0800 Message-ID: <20230915172818.761-6-shiju.jose@huawei.com> X-Mailer: git-send-email 2.35.1.windows.2 In-Reply-To: <20230915172818.761-1-shiju.jose@huawei.com> References: <20230915172818.761-1-shiju.jose@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.234] X-ClientProxiedBy: lhrpeml500001.china.huawei.com (7.191.163.213) To lhrpeml500006.china.huawei.com (7.191.161.198) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Fri, 15 Sep 2023 10:30:21 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777125806389301114 X-GMAIL-MSGID: 1777125806389301114 From: A Somasundaram The code contains PCC interfaces for RASF and RAS2 table, functions to send RASF commands as per ACPI 5.1 and RAS2 commands as per ACPI 6.5 & upwards revision. References for this implementation, ACPI specification, section 5.2.20 for RASF table, section 5.2.21 for RAS2 table and chapter 14 for PCC (Platform Communication Channel). Driver uses PCC interfaces to communicate to the ACPI HW. This code implements PCC interfaces and the functions to send the RASF/RAS2 commands to be used by OSPM. Signed-off-by: A Somasundaram Co-developed-by: Shiju Jose Signed-off-by: Shiju Jose --- drivers/acpi/Kconfig | 12 +- drivers/acpi/Makefile | 2 +- drivers/acpi/rasf_acpi.c | 26 --- drivers/acpi/rasf_acpi_common.c | 272 ++++++++++++++++++++++++++++++++ include/acpi/rasf_acpi.h | 40 +++++ 5 files changed, 322 insertions(+), 30 deletions(-) create mode 100755 drivers/acpi/rasf_acpi_common.c diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index e5fd8edc5b35..057f7fbc9887 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -283,10 +283,16 @@ config ACPI_RASF bool "ACPI RASF driver" depends on ACPI_PROCESSOR select MAILBOX + select PCC help - The driver adds support for extraction of RASF table from OS - system table. Driver adds platform device which binds to the - RASF memory driver. + The driver adds support for PCC (platform communication + channel) interfaces to communicate with the ACPI complaint + hardware platform supports RASF(RAS Feature table) or + and RAS2(RAS2 Feature table). + The driver adds support for RASF(extraction of RASF tables + from OS system table), PCC interfaces and OSPM interfaces to + send RASF & RAS2 commands. Driver adds platform device which + binds to the RASF/RAS2 memory driver. config ACPI_PROCESSOR tristate "Processor" diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index f8a1263f6128..dd62d936cbe1 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -104,7 +104,7 @@ obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o obj-$(CONFIG_ACPI_BGRT) += bgrt.o obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_acpi.o obj-$(CONFIG_ACPI_SPCR_TABLE) += spcr.o -obj-$(CONFIG_ACPI_RASF) += rasf_acpi.o +obj-$(CONFIG_ACPI_RASF) += rasf_acpi_common.o rasf_acpi.o obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o obj-$(CONFIG_ACPI_PPTT) += pptt.o obj-$(CONFIG_ACPI_PFRUT) += pfr_update.o pfr_telemetry.o diff --git a/drivers/acpi/rasf_acpi.c b/drivers/acpi/rasf_acpi.c index b30ba2a5e4ff..4c752fab9c4c 100755 --- a/drivers/acpi/rasf_acpi.c +++ b/drivers/acpi/rasf_acpi.c @@ -25,32 +25,6 @@ #include #include -static struct platform_device *rasf_add_platform_device(char *name, const void *data, - size_t size) -{ - int ret; - struct platform_device *pdev; - - pdev = platform_device_alloc(name, PLATFORM_DEVID_AUTO); - if (!pdev) - return NULL; - - ret = platform_device_add_data(pdev, data, size); - if (ret) - goto dev_put; - - ret = platform_device_add(pdev); - if (ret) - goto dev_put; - - return pdev; - -dev_put: - platform_device_put(pdev); - - return NULL; -} - int __init rasf_acpi_init(void) { acpi_status status; diff --git a/drivers/acpi/rasf_acpi_common.c b/drivers/acpi/rasf_acpi_common.c new file mode 100755 index 000000000000..3ee34f5d12d3 --- /dev/null +++ b/drivers/acpi/rasf_acpi_common.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * rasf_acpi_common.c - ACPI RASF table processing common functions + * + * (C) Copyright 2014, 2015 Hewlett-Packard Enterprises. + * + * Copyright (c) 2023 HiSilicon Limited. + * + * Support for + * RASF - ACPI 6.5 Specification, section 5.2.20 + * RAS2 - ACPI 6.5 Specification, section 5.2.21 + * PCC(Platform Communications Channel) - ACPI 6.5 Specification, + * chapter 14. + * + * Code contains common functions for RASF. + * PCC(Platform communication channel) interfaces for the RASF & RAS2 + * and the functions for sending RASF & RAS2 commands to the ACPI HW. + */ + +#define pr_fmt(fmt) "ACPI RASF COMMON: " fmt + +#include +#include +#include +#include +#include +#include + +static int rasf_check_pcc_chan(struct rasf_context *rasf_ctx) +{ + int ret = -EIO; + struct acpi_rasf_shared_memory __iomem *generic_comm_base = rasf_ctx->pcc_comm_addr; + ktime_t next_deadline = ktime_add(ktime_get(), rasf_ctx->deadline); + + while (!ktime_after(ktime_get(), next_deadline)) { + /* + * As per ACPI spec, the PCC space wil be initialized by + * platform and should have set the command completion bit when + * PCC can be used by OSPM + */ + if (readw_relaxed(&generic_comm_base->status) & RASF_PCC_CMD_COMPLETE) { + ret = 0; + break; + } + /* + * Reducing the bus traffic in case this loop takes longer than + * a few retries. + */ + udelay(10); + } + + return ret; +} + +/** + * rasf_send_pcc_cmd() - Send RASF command via PCC channel + * @rasf_ctx: pointer to the rasf context structure + * @cmd: command to send + * + * Returns: 0 on success, an error otherwise + */ +int rasf_send_pcc_cmd(struct rasf_context *rasf_ctx, u16 cmd) +{ + int ret = -EIO; + struct acpi_rasf_shared_memory *generic_comm_base = + (struct acpi_rasf_shared_memory *)rasf_ctx->pcc_comm_addr; + static ktime_t last_cmd_cmpl_time, last_mpar_reset; + static int mpar_count; + unsigned int time_delta; + + if (cmd == RASF_PCC_CMD_EXEC) { + ret = rasf_check_pcc_chan(rasf_ctx); + if (ret) + return ret; + } + + /* + * Handle the Minimum Request Turnaround Time(MRTT) + * "The minimum amount of time that OSPM must wait after the completion + * of a command before issuing the next command, in microseconds" + */ + if (rasf_ctx->pcc_mrtt) { + time_delta = ktime_us_delta(ktime_get(), last_cmd_cmpl_time); + if (rasf_ctx->pcc_mrtt > time_delta) + udelay(rasf_ctx->pcc_mrtt - time_delta); + } + + /* + * Handle the non-zero Maximum Periodic Access Rate(MPAR) + * "The maximum number of periodic requests that the subspace channel can + * support, reported in commands per minute. 0 indicates no limitation." + * + * This parameter should be ideally zero or large enough so that it can + * handle maximum number of requests that all the cores in the system can + * collectively generate. If it is not, we will follow the spec and just + * not send the request to the platform after hitting the MPAR limit in + * any 60s window + */ + if (rasf_ctx->pcc_mpar) { + if (mpar_count == 0) { + time_delta = ktime_ms_delta(ktime_get(), last_mpar_reset); + if (time_delta < 60 * MSEC_PER_SEC) { + pr_debug("PCC cmd not sent due to MPAR limit"); + return -EIO; + } + last_mpar_reset = ktime_get(); + mpar_count = rasf_ctx->pcc_mpar; + } + mpar_count--; + } + + /* Write to the shared comm region. */ + writew_relaxed(cmd, &generic_comm_base->command); + + /* Flip CMD COMPLETE bit */ + writew_relaxed(0, &generic_comm_base->status); + + /* Ring doorbell */ + ret = mbox_send_message(rasf_ctx->pcc_channel, &cmd); + if (ret < 0) { + pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n", + cmd, ret); + return ret; + } + + /* + * For READs we need to ensure the cmd completed to ensure + * the ensuing read()s can proceed. For WRITEs we dont care + * because the actual write()s are done before coming here + * and the next READ or WRITE will check if the channel + * is busy/free at the entry of this call. + * + * If Minimum Request Turnaround Time is non-zero, we need + * to record the completion time of both READ and WRITE + * command for proper handling of MRTT, so we need to check + * for pcc_mrtt in addition to CMD_READ + */ + if (cmd == RASF_PCC_CMD_EXEC || rasf_ctx->pcc_mrtt) { + ret = rasf_check_pcc_chan(rasf_ctx); + if (rasf_ctx->pcc_mrtt) + last_cmd_cmpl_time = ktime_get(); + } + + if (rasf_ctx->pcc_channel->mbox->txdone_irq) + mbox_chan_txdone(rasf_ctx->pcc_channel, ret); + else + mbox_client_txdone(rasf_ctx->pcc_channel, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(rasf_send_pcc_cmd); + +/** + * rasf_register_pcc_channel() - Register PCC channel + * @rasf_ctx: pointer to the rasf context structure + * + * Returns: 0 on success, an error otherwise + */ +int rasf_register_pcc_channel(struct rasf_context *rasf_ctx) +{ + u64 usecs_lat; + unsigned int len; + struct pcc_mbox_chan *pcc_chan; + struct mbox_client *rasf_mbox_cl; + struct acpi_pcct_hw_reduced *rasf_ss; + + rasf_mbox_cl = &rasf_ctx->mbox_client; + if (!rasf_mbox_cl || rasf_ctx->pcc_subspace_idx < 0) + return -EINVAL; + + pcc_chan = pcc_mbox_request_channel(rasf_mbox_cl, + rasf_ctx->pcc_subspace_idx); + + if (IS_ERR(pcc_chan)) { + pr_err("Failed to find PCC channel for subspace %d\n", + rasf_ctx->pcc_subspace_idx); + return -ENODEV; + } + rasf_ctx->pcc_chan = pcc_chan; + rasf_ctx->pcc_channel = pcc_chan->mchan; + /* + * The PCC mailbox controller driver should + * have parsed the PCCT (global table of all + * PCC channels) and stored pointers to the + * subspace communication region in con_priv. + */ + rasf_ss = rasf_ctx->pcc_channel->con_priv; + + if (!rasf_ss) { + pr_err("No PCC subspace found for RASF\n"); + pcc_mbox_free_channel(rasf_ctx->pcc_chan); + return -ENODEV; + } + + /* + * This is the shared communication region + * for the OS and Platform to communicate over. + */ + rasf_ctx->comm_base_addr = rasf_ss->base_address; + len = rasf_ss->length; + pr_debug("PCC subspace for RASF=0x%llx len=%d\n", + rasf_ctx->comm_base_addr, len); + + /* + * rasf_ss->latency is just a Nominal value. In reality + * the remote processor could be much slower to reply. + * So add an arbitrary amount of wait on top of Nominal. + */ + usecs_lat = RASF_NUM_RETRIES * rasf_ss->latency; + rasf_ctx->deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); + rasf_ctx->pcc_mrtt = rasf_ss->min_turnaround_time; + rasf_ctx->pcc_mpar = rasf_ss->max_access_rate; + rasf_ctx->pcc_comm_addr = acpi_os_ioremap(rasf_ctx->comm_base_addr, len); + pr_debug("pcc_comm_addr=%p\n", rasf_ctx->pcc_comm_addr); + + /* Set flag so that we dont come here for each CPU. */ + rasf_ctx->pcc_channel_acquired = true; + + return 0; +} +EXPORT_SYMBOL_GPL(rasf_register_pcc_channel); + +/** + * rasf_unregister_pcc_channel() - Unregister PCC channel + * @rasf_ctx: pointer to the rasf context structure + * + * Returns: 0 on success, an error otherwise + */ +int rasf_unregister_pcc_channel(struct rasf_context *rasf_ctx) +{ + if (!rasf_ctx->pcc_chan) + return -EINVAL; + + pcc_mbox_free_channel(rasf_ctx->pcc_chan); + + return 0; +} +EXPORT_SYMBOL_GPL(rasf_unregister_pcc_channel); + +/** + * rasf_add_platform_device() - Add a platform device for RASF + * @name: name of the device we're adding + * @data: platform specific data for this platform device + * @size: size of platform specific data + * + * Returns: pointer to platform device on success, an error otherwise + */ +struct platform_device *rasf_add_platform_device(char *name, const void *data, + size_t size) +{ + int ret; + struct platform_device *pdev; + + pdev = platform_device_alloc(name, PLATFORM_DEVID_AUTO); + if (!pdev) + return NULL; + + ret = platform_device_add_data(pdev, data, size); + if (ret) + goto dev_put; + + ret = platform_device_add(pdev); + if (ret) + goto dev_put; + + return pdev; + +dev_put: + platform_device_put(pdev); + + return NULL; +} diff --git a/include/acpi/rasf_acpi.h b/include/acpi/rasf_acpi.h index 1c4c3e94d472..e91a451c5dc1 100755 --- a/include/acpi/rasf_acpi.h +++ b/include/acpi/rasf_acpi.h @@ -11,9 +11,49 @@ #define _RASF_ACPI_H #include +#include +#include #include +#include + +#define RASF_PCC_CMD_COMPLETE 1 + +/* RASF specific PCC commands */ +#define RASF_PCC_CMD_EXEC 0x01 #define RASF_FAILURE 0 #define RASF_SUCCESS 1 +/* + * Arbitrary Retries for PCC commands. + */ +#define RASF_NUM_RETRIES 600 + +/* + * Data structures for PCC communication and RASF table + */ +struct rasf_context { + struct device *dev; + int id; + struct mbox_client mbox_client; + struct mbox_chan *pcc_channel; + struct pcc_mbox_chan *pcc_chan; + void __iomem *pcc_comm_addr; + u64 comm_base_addr; + int pcc_subspace_idx; + bool pcc_channel_acquired; + ktime_t deadline; + unsigned int pcc_mpar; + unsigned int pcc_mrtt; + spinlock_t spinlock; /* Lock to provide mutually exclusive access to PCC channel */ + struct device *scrub_dev; + u8 n_regions; + const struct rasf_hw_scrub_ops *ops; +}; + +struct platform_device *rasf_add_platform_device(char *name, const void *data, + size_t size); +int rasf_send_pcc_cmd(struct rasf_context *rasf_ctx, u16 cmd); +int rasf_register_pcc_channel(struct rasf_context *rasf_ctx); +int rasf_unregister_pcc_channel(struct rasf_context *rasf_ctx); #endif /* _RASF_ACPI_H */