From patchwork Thu Mar 13 18:34:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015775 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2080.outbound.protection.outlook.com [40.107.243.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD6011DDC3B; Thu, 13 Mar 2025 18:35:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.243.80 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890917; cv=fail; b=Y5Uzx44K7KyMysiwA7py3bJ1m+Xl8Nj+vCVEZ1OOeJFd3WP1XItnXBkRXDo9oszcmwNT4oA10jEut3eNCW0/3QECNBIbOancTNgKWcbUFDGKlHLKwvewY2Tsh8GvaUo0HcfreLP+ybd6EkE1JsXhPaiCYtuHWN6EBGfzfmoKY24= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890917; c=relaxed/simple; bh=3dBTFmvo7vgPk2w/Mt+BS8EOFbNr/NyzgMOZ9bhCTis=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KBQ2fG27rd2MkmiVXCweGKDaCV+Ca/WwWnXX8i1ykjkd4yPzEQN5UfDZM4WymfAVRyQYdsKc/hG7Aaiy5tbrqCM41vufzfJ6kjVcehAD3HTTg2achbQgXQop5HUrZI9y8A4e3McDn5/0f7IUrxgRYFz9ZDasNZ5bjZ0MARDQHOk= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=xZQrVl++; arc=fail smtp.client-ip=40.107.243.80 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="xZQrVl++" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Ry9ujEhiOCeY44/2DW39irZLSNZP+RJVZvLdWZNuZUkFsW8v9PC9tuIp2i6n2IHt/x+gEeVCm7WIFHwHdxR1aDsu9/1mXrQ7duycqC48vBUnMQtVBfk2e343WDauuzztraARG6L1WDm8wij1mxnhthHARMzmLsuUVB/2xyGGBwKpzWFFiwFdt0FVdKrR6zC2xuD8EOfj2p/CzfgYNR0VzVHecbwWt5Urdju2w5XU06z9E5Ul1i86GoiM024BGoMx2r1t6VD8c9FoYruW0BOCMPgR42mofDNUETmkSqM8WR6Vmi++1c1E5w4zHqLrRnO+kO8kHoGc5nZFX4wJMcx9hQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=v2Q4rXVI2nsnBUhtfzCfZGh07W8hwLWzD0WtftEPjRA=; b=PL/q58IrS6Aohwme3seCJR7rmJprMMMtqia5Znq7VXd+s15filbMg+vU7YSL+76NUWxOJNXuxHxjflXlKnUfubn4CtXJEWn5w0L1bxKMitPBbZyHE429tQyB9ptn9P7O43ekAgXsXiSEkMGAl487aWS2TYAJDMF9I43QMF+lbwYmu+D6jzoSufes+SV7B8Fkjle6Sh6sbbs76n4B9Qy0XlC/VRUDuwJvoCPhWiHwzyebO3k0snA+N8n5f8mwk1+6BGyovJjOyCMwly/IknsCu7SBwYDNR6G2kixE0eeZogaWXmscmtM5hPeEjojGfjGe3QxoNx8zHMLU3mlGv6lW9g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=v2Q4rXVI2nsnBUhtfzCfZGh07W8hwLWzD0WtftEPjRA=; b=xZQrVl++KYE3mbOWZ7Zg+xDBCWOc7BqUf4rXS7yT6Gf0U+4paXFvfGVgs3o82nNVgLwAjFmysKV+G3AB0QP2vQfdHrmd+FbSczT+BsqN//PMwPsiDcgfkbt+L80mt2D3FMUDPFYUJnQfOcvIftDN1lUbCdAsPWf45pqiXPnraIw= Received: from MN2PR18CA0007.namprd18.prod.outlook.com (2603:10b6:208:23c::12) by SJ2PR12MB9006.namprd12.prod.outlook.com (2603:10b6:a03:540::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 18:35:12 +0000 Received: from BL6PEPF00020E62.namprd04.prod.outlook.com (2603:10b6:208:23c:cafe::af) by MN2PR18CA0007.outlook.office365.com (2603:10b6:208:23c::12) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.25 via Frontend Transport; Thu, 13 Mar 2025 18:35:11 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by BL6PEPF00020E62.mail.protection.outlook.com (10.167.249.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:35:11 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:35:08 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 01/10] spi: espi_amd: Add AMD eSPI controller driver support Date: Fri, 14 Mar 2025 00:04:31 +0530 Message-ID: <20250313183440.261872-2-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL6PEPF00020E62:EE_|SJ2PR12MB9006:EE_ X-MS-Office365-Filtering-Correlation-Id: 275d942d-cee6-41d3-b3b9-08dd625dc9c9 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|82310400026|376014|36860700013; X-Microsoft-Antispam-Message-Info: IyPBnb35txqtwR0s7PIOcWPJANVdKMp4YiewzxUkauSM3qhXI66JPBwSkGOEH2isWXW4TPqH/d3gLvqHjgKNpueyHFEKwdEOeWh9P88+3vIFO2kf1A/NQhefQWw++p2NkXSP+y0vhLyirnjTUEwJsMVaYeCQcUS4+mgrG2I22wGKXInUYs5BVus48/m1PnuU2DFk+Q4kbN4V6kW/eFy2J3aLHi5RMfXCfa7Azcjunrz4a36LOGbpGevXMb0SoQDDXIlmrsORQnSp6BeqQKOTqoWNj0E920mI+0cVsq05j1uJYIXJD9D+Ep5Z4nDSNfWObewBN8LtonU5C89RwwTzWb31jNUKzLIzDwpSmZiOwBRIpgQRfCy0t3SDaqpKeM8rOqNX7MneRpp/YyJ6qNZDkvpmAC9aOII8g95mFGdUfggN2AG5fLQS5yijJMbD+aC+E+VbwL1fmDk4bEJ0X55lxN6IUhGD+H3V41Md811XS3CBRIGYXSnn9Bcteqg6oUn7fbNu+MMHTrpBkmjuUruPF65QkPd4BY/cyrjg8reYYLV95b3fQSL0twJsTSBAJODOq+389yoGE8REjHzphTd75Wy8cH4k99MFYcG8GCieL4o7/p/G1PCDXMcIShxP/MKKa46GiunM/lJWecruBu7yrRrlagP/oSI1KOWBrnu0E0dywCcNQbTL+qI1yr3jEx+hv/WjQp81R683GihyKaXRxmzQA3BvmwBdO7Eri+EZR4B0CTYh9TAOxQBW0DgVlj4UHFwFQK2m8e9RhrW1QpzYhDdQEagh1x8nGR0ddx7/9iFfQl0A5rotbpmYsvgvn45YFnCwPfaTL89ryksSNDAZQbh4QWds75B92uGxhXc5E6auEYhHxDt/1x/PfVj+V2uiL0zMe/k/HgkIbGrxFqrY8Tqe+SORL/CEpslZnY8H0XovT3cwZTsgvZ70+eZEcKndc1bnasKLtIqNkL5hZ06y4AcfkWWFk4OIGieEj6Qqw6cD1NX817NH4kqzfkRV1z5lttjCfHI/EF7ClF3Fu5ea63pE5jFgLP/3qOGZxC+bB0pt1URk/8ZI1SR9rpKT+eMuirM2k/WqC0Hjoa7t11+nU+vDkYf2XkJ31M8OgKxfoShSDZW2+Bmqk3I3LmiAcj1jvy/YM/+zh3tSQaeSiRU9q3QUF8hiLOYAbz3AJnOgVgei97quNmGQPiMSMY5oMg9Cs5lrqooRAL20/3LZmYKzgweapL5coq4xgmFKP/MIbvsUZLLdR53IxR2LTL7bOlXn81C5k6/SyiEVdHTJCdaw6Qf+u5ehx0EfYwhf/MM95YPNYhbE85x3aC7PWrNjAnbKV56XpIQAS8AvP1miC9eXFa2bq/545EfpONr43BZavyBm7SDy0RcaLvzeRRcOTdEwlooue8e6lkwToOe6mIEi0N0X1vkM33usSLsyBrw/uzGnQXI2S2RkZAhowu8AKMlx499HRT9nQDvLh9LLTsGhqA== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(82310400026)(376014)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:35:11.2148 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 275d942d-cee6-41d3-b3b9-08dd625dc9c9 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BL6PEPF00020E62.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR12MB9006 This patch enables core eSPI controller initialization in AMD embedded platforms, supporting communication with eSPI slave devices through the device file entry. Currently, the eSPI controller in AMD embedded platforms has only one chip select line enabled, which is connected to the Embedded Controller (EC). Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- MAINTAINERS | 6 + drivers/spi/Kconfig | 10 + drivers/spi/Makefile | 2 + drivers/spi/espi-amd-core.c | 883 +++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd-dev.c | 128 +++++ drivers/spi/espi-amd-err.h | 50 ++ drivers/spi/espi-amd-slave.h | 109 +++++ drivers/spi/espi-amd.h | 291 ++++++++++++ 8 files changed, 1479 insertions(+) create mode 100644 drivers/spi/espi-amd-core.c create mode 100644 drivers/spi/espi-amd-dev.c create mode 100644 drivers/spi/espi-amd-err.h create mode 100644 drivers/spi/espi-amd-slave.h create mode 100644 drivers/spi/espi-amd.h diff --git a/MAINTAINERS b/MAINTAINERS index 9f052994b7d4..c102dcce5892 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1059,6 +1059,12 @@ S: Supported F: drivers/gpu/drm/amd/display/dc/dml/ F: drivers/gpu/drm/amd/display/dc/dml2/ +AMD ESPI DRIVER +M: Raju Rangoju +L: linux-spi@vger.kernel.org +S: Supported +F: drivers/spi/espi-amd* + AMD FAM15H PROCESSOR POWER MONITORING DRIVER M: Huang Rui L: linux-hwmon@vger.kernel.org diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ea8a31032927..72b950f3eccb 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -1238,6 +1238,16 @@ config SPI_AMD help Enables SPI controller driver for AMD SoC. +config SPI_AMD_ESPI + tristate "AMD eSPI controller" + depends on X86_64 || SPI_MASTER || COMPILE_TEST + help + AMD SOCs contains multiple SPI controllers, including a dedicated + eSPI controller. This config enables eSPI controller driver for + AMD SoC. AMD eSPI driver aims to comprehensive support for the + eSPI protocol, including initialization of eSPI controller + and slave devices and eSPI channel specific commands. + # # Add new SPI master controllers in alphabetical order above this line # diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 9db7554c1864..0dec8ad30967 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -159,6 +159,8 @@ obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o obj-$(CONFIG_SPI_ZYNQ_QSPI) += spi-zynq-qspi.o obj-$(CONFIG_SPI_ZYNQMP_GQSPI) += spi-zynqmp-gqspi.o obj-$(CONFIG_SPI_AMD) += spi-amd.o +obj-$(CONFIG_SPI_AMD_ESPI) += espi-amd.o +espi-amd-objs := espi-amd-core.o espi-amd-dev.o # SPI slave protocol handlers obj-$(CONFIG_SPI_SLAVE_TIME) += spi-slave-time.o diff --git a/drivers/spi/espi-amd-core.c b/drivers/spi/espi-amd-core.c new file mode 100644 index 000000000000..72a625b8b16d --- /dev/null +++ b/drivers/spi/espi-amd-core.c @@ -0,0 +1,883 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD eSPI controller driver + * + * Copyright (c) 2025, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Authors: Krishnamoorthi M + * Akshata MukundShetty + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#include "espi-amd.h" +#include "espi-amd-slave.h" +#include "espi-amd-err.h" + +#define ESPI_CH_READY_TIMEOUT_US 200 + +/* + * In case of get configuration command, hdata0 contains bits[15:8] of the slave register address + * and hdata1 contains bits[7:0] of the slave register address. + */ +#define ESPI_CONFIGURATION_HDATA0(a) (((a) >> 8) & GENMASK(7, 0)) +#define ESPI_CONFIGURATION_HDATA1(a) ((a) & GENMASK(7, 0)) +#define ESPI_INTR_MASK GENMASK(31, 0) + +static int amd_espi_set_initial_config(struct amd_espi *amd_espi); + +static void amd_espi_clear_status(struct amd_espi *amd_espi) +{ + u32 status = readl(ESPI_BASE + AMD_ESPI_SLAVE0_INT_STS_REG); + + if (status) + writel(status, (ESPI_BASE + AMD_ESPI_SLAVE0_INT_STS_REG)); +} + +void amd_espi_clr_all_intr(struct amd_espi *amd_espi) +{ + /* Set all bits to clear all the interrupt */ + writel(ESPI_INTR_MASK, (ESPI_BASE + AMD_ESPI_SLAVE0_INT_STS_REG)); +} + +static int amd_espi_check_error_status(struct amd_espi *amd_espi, u32 status) +{ + int ret = CB_SUCCESS; + + if (!(status & ESPI_DNCMD_INT)) { + ret = ESPI_DNCMD_INT; + dev_err(amd_espi->dev, "eSPI downstream command completion failure\n"); + } else if (status & ESPI_BUS_ERR_INT) { + ret = ESPI_BUS_ERR_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_BUS_TIMING]); + } else if (status & ESPI_WAIT_TIMEOUT_INT) { + ret = ESPI_WAIT_TIMEOUT_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_BUS_WAIT_STATE]); + } else if (status & ESPI_CRC_ERR_INT) { + ret = ESPI_CRC_ERR_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_CRC]); + } else if (status & ESPI_NO_RESP_INT) { + ret = ESPI_NO_RESP_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_NO_RESP]); + } else if (status & ESPI_FATAL_ERR_INT) { + ret = ESPI_FATAL_ERR_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_FATAL_ERR]); + } else if (status & ESPI_NON_FATAL_ERR_INT) { + ret = ESPI_NON_FATAL_ERR_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_NON_FATAL_ERR]); + } else if (status & ESPI_INVALID_RESP_CODE_INT) { + ret = ESPI_INVALID_RESP_CODE_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_INVALID_RESP_CODE]); + } else if (status & ESPI_INVALID_CYCLE_TYPE_INT) { + ret = ESPI_INVALID_CYCLE_TYPE_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_INVALID_CYCLE_TYPE]); + } else if (status & ESPI_UNSUCCESS_CPL_RECV_INT) { + ret = ESPI_UNSUCCESS_CPL_RECV_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_UNSUCCESS_CPL_RECV]); + } else if (status & ESPI_ILLEGAL_RESP_TAG_INT) { + ret = ESPI_ILLEGAL_RESP_TAG_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_ILLEGAL_RESP_TAG]); + } else if (status & ESPI_ILLEGAL_RESP_LEN_INT) { + ret = ESPI_ILLEGAL_RESP_LEN_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_ILLEGAL_RESP_LEN]); + } else if (status & ESPI_RX_OOB_OVERFLOW_INT) { + ret = ESPI_RX_OOB_OVERFLOW_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_OOB_DATA_LEN]); + } else if (status & ESPI_RX_PC_MSG_OVERFLOW_INT) { + ret = ESPI_RX_PC_MSG_OVERFLOW_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_PC_MSG_DATA]); + } else if (status & ESPI_RX_FLASH_MSG_OVERFLOW_INT) { + ret = ESPI_RX_FLASH_MSG_OVERFLOW_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_FLASH_DATA_LEN]); + } else if (status & ESPI_PROTOCOL_ERR_INT) { + ret = ESPI_PROTOCOL_ERR_INT; + dev_err(amd_espi->dev, "%s\n", espi_error_codes[POS_PROTOCOL_ERR]); + } + + return ret; +} + +static int amd_espi_alloc_cmd_data(struct espi_txcmd *cmd) +{ + u32 size = 0; + + switch (cmd->hdr0.cmd_type) { + case SET_CONFIGURATION: + case GET_CONFIGURATION: + case IN_BAND_RESET: + size = 1; + default: + break; + } + + if (!size) + return -EOPNOTSUPP; + + size = DATA_SIZE_ROUNDOFF_4(size); + cmd->data = kzalloc(size, GFP_KERNEL); + + if (!cmd->data) + return -ENOMEM; + + return CB_SUCCESS; +} + +static void amd_espi_send_downstream_data(struct amd_espi *amd_espi, struct espi_txcmd *cmd) +{ + union espi_txdata *data = cmd->data; + + /* Write first 4 bytes of data - common for all eSPI commands */ + writel(data->val, (ESPI_BASE + AMD_ESPI_DS_DATA_REG0)); +} + +static void amd_espi_cmd_reg_dump(struct device *dev, struct espi_txcmd *cmd) +{ + dev_err(dev, "eSPI command packet:\n" + "Header-0: %08x\nHeader-1: %08x\n" + "Header-2: %08x\nData: %08x\n", + cmd->hdr0.val, cmd->hdr1.val, cmd->hdr2.val, cmd->data->val); +} + +static int amd_espi_send_cmd(struct amd_espi *amd_espi, struct espi_txcmd *cmd) +{ + u32 status; + int ret; + + /* Wait until HW is ready to send the command */ + ret = readx_poll_timeout(ioread32, ESPI_BASE + AMD_ESPI_DS_HEADER_REG0, + status, (status & BIT(3)) == 0, ESPI_MSG_DELAY_MIN_US, + ESPI_RESP_MAX_TIMEOUT_US); + if (ret) { + dev_err(amd_espi->dev, "eSPI controller is not ready to accept commands\n"); + amd_espi_cmd_reg_dump(amd_espi->dev, cmd); + return ESPI_DNCMD_INT; + } + amd_espi_clear_status(amd_espi); + + writel(cmd->hdr1.val, (ESPI_BASE + AMD_ESPI_DS_HEADER_REG1)); + writel(cmd->hdr2.val, (ESPI_BASE + AMD_ESPI_DS_HEADER_REG2)); + + amd_espi_send_downstream_data(amd_espi, cmd); + + writel(cmd->hdr0.val, (ESPI_BASE + AMD_ESPI_DS_HEADER_REG0)); + + /* Wait until HW successfully sent the packet */ + ret = readx_poll_timeout(ioread32, ESPI_BASE + AMD_ESPI_DS_HEADER_REG0, + status, (status & BIT(3)) == 0, ESPI_MSG_DELAY_MIN_US, + ESPI_RESP_MAX_TIMEOUT_US); + if (ret) { + dev_err(amd_espi->dev, "eSPI timed out waiting for command to complete\n"); + amd_espi_cmd_reg_dump(amd_espi->dev, cmd); + return ESPI_DNCMD_INT; + } + + /* Wait for DS command completion interrupt */ + ret = readx_poll_timeout(ioread32, ESPI_BASE + AMD_ESPI_SLAVE0_INT_STS_REG, + status, status != 0, ESPI_MSG_DELAY_MIN_US, + ESPI_RESP_MAX_TIMEOUT_US); + if (ret) { + dev_err(amd_espi->dev, "eSPI command completion interrupt error (status = 0x%x)\n", + status); + amd_espi_cmd_reg_dump(amd_espi->dev, cmd); + return -ETIMEDOUT; + } + + ret = amd_espi_check_error_status(amd_espi, status); + if (ret != CB_SUCCESS) { + amd_espi_cmd_reg_dump(amd_espi->dev, cmd); + dev_err(amd_espi->dev, "eSPI status register: 0x%x\n", status); + } + + if (ret == ESPI_NO_RESP_INT || ret == ESPI_CRC_ERR_INT) { + dev_info(amd_espi->dev, "Triggering Inband-reset after CRC/NO_RESP Error\n"); + if (amd_espi_inband_reset(amd_espi) != CB_SUCCESS) + dev_err(amd_espi->dev, "In-band reset failed!\n"); + } + + /* Clear downstream command completion interrupt after command completion */ + writel(ESPI_DNCMD_INT, ESPI_BASE + AMD_ESPI_SLAVE0_INT_STS_REG); + + return ret; +} + +int amd_espi_inband_reset(struct amd_espi *amd_espi) +{ + int ret; + struct espi_txcmd cmd = { + .hdr0 = { + .cmd_type = IN_BAND_RESET, + .cmd_status = 1, + }, + }; + + ret = amd_espi_alloc_cmd_data(&cmd); + if (ret) + return ret; + + ret = amd_espi_send_cmd(amd_espi, &cmd); + if (ret != CB_SUCCESS) { + kfree(cmd.data); + return ret; + } + + ret = amd_espi_set_initial_config(amd_espi); + + kfree(cmd.data); + return ret; +} + +int amd_espi_set_iomode(struct amd_espi *amd_espi, u32 *slave_config, u32 *ctrlr_config, + u8 io_mode) +{ + struct espi_master *master = amd_espi->master; + + switch (io_mode) { + case IO_MODE_QUAD: + if (master->caps.io_mode_quad && espi_slave_supports_quad_io(*slave_config)) { + *ctrlr_config = ESPI_CNTRL_SET_IO_MODE(*ctrlr_config, IO_MODE_QUAD); + *slave_config = ESPI_SLAVE_SET_IO_MODE(*slave_config, + ESPI_SLAVE_IO_MODE_SEL_QUAD); + break; + } + dev_info(amd_espi->dev, "eSPI Quad IO not supported. Dropping to Dual mode.\n"); + fallthrough; + case IO_MODE_DUAL: + if (master->caps.io_mode_dual && espi_slave_supports_dual_io(*slave_config)) { + *ctrlr_config = ESPI_CNTRL_SET_IO_MODE(*ctrlr_config, IO_MODE_DUAL); + *slave_config = ESPI_SLAVE_SET_IO_MODE(*slave_config, + ESPI_SLAVE_IO_MODE_SEL_DUAL); + break; + } + dev_info(amd_espi->dev, "eSPI Dual IO not supported. Dropping to Single mode.\n"); + fallthrough; + case IO_MODE_SINGLE: + default: + if (master->caps.io_mode_single && espi_slave_supports_single_io(*slave_config)) { + *ctrlr_config = ESPI_CNTRL_SET_IO_MODE(*ctrlr_config, IO_MODE_SINGLE); + *slave_config = ESPI_SLAVE_SET_IO_MODE(*slave_config, + ESPI_SLAVE_IO_MODE_SEL_SINGLE); + } else { + dev_err(amd_espi->dev, "%s, eSPI IO mode not supported\n", __func__); + return -EOPNOTSUPP; + } + } + + return CB_SUCCESS; +} + +int amd_espi_set_freqmode(struct amd_espi *amd_espi, u32 *slave_config, u32 *ctrlr_config, + u8 op_freq) +{ + struct espi_master *master = amd_espi->master; + + switch (op_freq) { + case SLAVE_OP_FREQ_66: + if (master->caps.op_freq_66 && espi_slave_supports_66_mhz(*slave_config)) { + *ctrlr_config = ESPI_CNTRL_SET_OP_FREQ(*ctrlr_config, + CNTRL_SLAVE0_OP_FREQ_66); + *slave_config = ESPI_SLAVE_SET_OP_FREQ(*slave_config, + ESPI_SLAVE_OP_FREQ_SEL_66_MHZ); + break; + } + dev_info(amd_espi->dev, "eSPI frequency 66 MHz not supported. Dropping to 33MHz.\n"); + fallthrough; + case SLAVE_OP_FREQ_33: + if (master->caps.op_freq_33 && ((espi_slave_supports_66_mhz(*slave_config)) || + (espi_slave_supports_33_mhz(*slave_config)))) { + *ctrlr_config = ESPI_CNTRL_SET_OP_FREQ(*ctrlr_config, + CNTRL_SLAVE0_OP_FREQ_33); + *slave_config = ESPI_SLAVE_SET_OP_FREQ(*slave_config, + ESPI_SLAVE_OP_FREQ_SEL_33_MHZ); + break; + } + dev_info(amd_espi->dev, "eSPI frequency 33 MHz not supported. Dropping to 16MHz.\n"); + fallthrough; + case SLAVE_OP_FREQ_16: + default: + if (master->caps.op_freq_16 && ((espi_slave_supports_66_mhz(*slave_config)) || + (espi_slave_supports_33_mhz(*slave_config)) || + (espi_slave_supports_16_mhz(*slave_config)))) { + *ctrlr_config = ESPI_CNTRL_SET_OP_FREQ(*ctrlr_config, + CNTRL_SLAVE0_OP_FREQ_16); + *slave_config = ESPI_SLAVE_SET_OP_FREQ(*slave_config, + ESPI_SLAVE_OP_FREQ_SEL_16_MHZ); + } else { + dev_err(amd_espi->dev, "%s, eSPI frequency mode not supported\n", __func__); + return -EOPNOTSUPP; + } + } + + return CB_SUCCESS; +} + +static int amd_espi_get_config(struct amd_espi *amd_espi, u16 slave_reg_address, u32 *config) +{ + int ret; + struct espi_txcmd cmd = { + .hdr0 = { + .cmd_type = GET_CONFIGURATION, + .cmd_status = 1, + .hdata0 = ESPI_CONFIGURATION_HDATA0(slave_reg_address), + .hdata1 = ESPI_CONFIGURATION_HDATA1(slave_reg_address), + }, + }; + + ret = amd_espi_alloc_cmd_data(&cmd); + if (ret) + return ret; + + ret = amd_espi_send_cmd(amd_espi, &cmd); + if (ret != CB_SUCCESS) { + kfree(cmd.data); + return ret; + } + + *config = readl(ESPI_BASE + AMD_ESPI_DS_HEADER_REG1); + + kfree(cmd.data); + return CB_SUCCESS; +} + +int amd_espi_get_channel_config(struct amd_espi *amd_espi) +{ + u32 chnl_config; + u32 ret = 0; + + if (amd_espi_get_config(amd_espi, ESPI_SLAVE_PERIPH_CFG, &chnl_config) == CB_SUCCESS) { + if (chnl_config & ESPI_SLAVE_CHANNEL_ENABLE) + ret |= CHANNEL_MODE_PC; + } + + if (amd_espi_get_config(amd_espi, ESPI_SLAVE_VW_CFG, &chnl_config) == CB_SUCCESS) { + if (chnl_config & ESPI_SLAVE_CHANNEL_ENABLE) + ret |= CHANNEL_MODE_VW; + } + + return (ret == 0) ? -EOPNOTSUPP : ret; +} + +int amd_espi_get_general_config(struct amd_espi *amd_espi, u32 *config) +{ + return amd_espi_get_config(amd_espi, ESPI_SLAVE_GENERAL_CAPS_CFG, config); +} + +int amd_espi_set_config(struct amd_espi *amd_espi, u32 config, u16 slave_reg_address) +{ + int ret; + struct espi_txcmd cmd = { + .hdr0 = { + .cmd_type = SET_CONFIGURATION, + .cmd_status = 1, + .hdata0 = ESPI_CONFIGURATION_HDATA0(slave_reg_address), + .hdata1 = ESPI_CONFIGURATION_HDATA1(slave_reg_address), + }, + .hdr1 = { + .val = config, + }, + }; + + ret = amd_espi_alloc_cmd_data(&cmd); + if (ret) + return ret; + + ret = amd_espi_send_cmd(amd_espi, &cmd); + kfree(cmd.data); + + return ret; +} + +int amd_espi_set_general_conf(struct amd_espi *amd_espi, struct config *dev) +{ + u32 ctrlr_config = readl(ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG); + u32 slave_config; + int status; + + status = amd_espi_get_general_config(amd_espi, &slave_config); + if (status != CB_SUCCESS) + return status; + + if (amd_espi->master->caps.alert_mode == 1) { + slave_config |= ESPI_SLAVE_ALERT_MODE_PIN; + ctrlr_config |= ESPI_CNTRL_SLAVE0_ALERT_MODE; + } + + if (amd_espi->master->caps.crc_check_support == 1) { + slave_config |= ESPI_SLAVE_CRC_ENABLE; + ctrlr_config |= ESPI_CNTRL_SLAVE0_CRC_CHECK_EN; + } + + status = amd_espi_set_iomode(amd_espi, &slave_config, &ctrlr_config, dev->io_mode); + if (status != CB_SUCCESS) { + dev_err(amd_espi->dev, "%s, IO mode not supported\n", __func__); + return -EOPNOTSUPP; + } + + status = amd_espi_set_freqmode(amd_espi, &slave_config, &ctrlr_config, dev->op_freq); + if (status != CB_SUCCESS) { + dev_err(amd_espi->dev, "%s, Operating frequency not supported\n", __func__); + return -EOPNOTSUPP; + } + + status = amd_espi_set_config(amd_espi, slave_config, ESPI_SLAVE_GENERAL_CAPS_CFG); + if (status != CB_SUCCESS) + return status; + + writel(ctrlr_config, (ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG)); + + return CB_SUCCESS; +} + +static int amd_espi_wait_channel_ready(struct amd_espi *amd_espi, u32 slave_reg_addr) +{ + u32 config; + int ret; + + udelay(ESPI_CH_READY_TIMEOUT_US); + ret = amd_espi_get_config(amd_espi, slave_reg_addr, &config); + if (ret != CB_SUCCESS) + return ret; + + if (!!(config & ESPI_SLAVE_CHANNEL_READY)) { + ret = CB_SUCCESS; + } else { + ret = -ETIMEDOUT; + dev_err(amd_espi->dev, "Channel is not ready after %d usec (slave addr: 0x%x)\n", + ESPI_CH_READY_TIMEOUT_US, slave_reg_addr); + } + + return ret; +} + +static void amd_espi_enable_ctrlr_channel(struct amd_espi *amd_espi, u32 channel_en) +{ + u32 reg = readl(ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG); + + writel(reg | channel_en, (ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG)); +} + +static int amd_espi_set_channel_config(struct amd_espi *amd_espi, u32 slave_config, + u32 slave_reg_addr, u32 ctrlr_enable) +{ + int ret = amd_espi_set_config(amd_espi, slave_config, slave_reg_addr); + + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Channel configuration failed\n"); + return ret; + } + + /* Channel already enabled */ + if (!(slave_config & ESPI_SLAVE_CHANNEL_ENABLE)) + return CB_SUCCESS; + + ret = amd_espi_wait_channel_ready(amd_espi, slave_reg_addr); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Channel is not ready\n"); + return ret; + } + + amd_espi_enable_ctrlr_channel(amd_espi, ctrlr_enable); + + return CB_SUCCESS; +} + +int amd_espi_setup_periph_channel(struct amd_espi *amd_espi, u32 slave_caps) +{ + /* Peripheral channel requires BME bit to be set when enabling */ + const u32 slave_en_mask = ESPI_SLAVE_CHANNEL_ENABLE | ESPI_SLAVE_PERIPH_BUS_MASTER_ENABLE; + struct espi_master *master = amd_espi->master; + u32 slave_config; + int ret; + + ret = amd_espi_get_config(amd_espi, ESPI_SLAVE_PERIPH_CFG, &slave_config); + if (ret != CB_SUCCESS) + return ret; + + /* Check if PC is already enabled */ + if (slave_config & ESPI_SLAVE_CHANNEL_ENABLE) + return CB_SUCCESS; + + /* + * Peripheral channel is the only one which is enabled on reset. So, if the mainboard + * wants to disable it, set configuration to disable peripheral channel. It also + * requires that BME bit be cleared. + */ + if (master->caps.periph_ch_en) { + if (!(slave_caps & ESPI_SLAVE_PERIPH_CH_SUPP)) { + dev_err(amd_espi->dev, "eSPI slave doesn't support periph channel!\n"); + return -EOPNOTSUPP; + } + slave_config |= slave_en_mask; + } else { + slave_config &= ~slave_en_mask; /* If master does not support make it to 0 */ + } + + return amd_espi_set_channel_config(amd_espi, slave_config, ESPI_SLAVE_PERIPH_CFG, + CHANNEL_MODE_PC); +} + +int amd_espi_setup_vw_channel(struct amd_espi *amd_espi, u32 slave_caps) +{ + struct espi_master *master = amd_espi->master; + u32 slave_vw_caps, slave_config; + int ret; + + if (!master->caps.vw_ch_en) { + dev_err(amd_espi->dev, "Master doesn't support VW channel\n"); + return -EOPNOTSUPP; + } + + if (!(slave_caps & ESPI_SLAVE_VW_CH_SUPP)) { + dev_err(amd_espi->dev, "eSPI slave doesn't support VW channel\n"); + return -EOPNOTSUPP; + } + + ret = amd_espi_get_config(amd_espi, ESPI_SLAVE_VW_CFG, &slave_vw_caps); + if (ret != CB_SUCCESS) + return ret; + + slave_config = slave_vw_caps | ESPI_SLAVE_CHANNEL_ENABLE; + + /* Check if VW channel is already enabled */ + if (slave_config & ESPI_SLAVE_CHANNEL_ENABLE) + return CB_SUCCESS; + + return amd_espi_set_channel_config(amd_espi, slave_config, ESPI_SLAVE_VW_CFG, + CHANNEL_MODE_VW); +} + +static int amd_espi_get_master_cap(struct amd_espi *amd_espi, struct espi_master *master) +{ + u32 master_cap_reg, info; + + master_cap_reg = readl(ESPI_BASE + AMD_ESPI_MASTER_CAP_REG); + + /* Supported channels by master */ + if (master_cap_reg & BIT(0)) + master->caps.flash_ch_en = 1; + + if (master_cap_reg & BIT(1)) + master->caps.oob_ch_en = 1; + + if (master_cap_reg & BIT(2)) + master->caps.vw_ch_en = 1; + + if (master_cap_reg & BIT(3)) + master->caps.periph_ch_en = 1; + + /* eSPI version */ + master->caps.espi_version = ESPI_GET_ESPI_VERSION(master_cap_reg); + + /* Operating frequency supported by master */ + info = ESPI_GET_FREQ(master_cap_reg); + switch (info) { + case CNTRL_OP_FREQ_66: + master->caps.op_freq_66 = 1; + fallthrough; + case CNTRL_OP_FREQ_33: + master->caps.op_freq_33 = 1; + fallthrough; + case CNTRL_OP_FREQ_16: + master->caps.op_freq_16 = 1; + break; + default: + dev_err(amd_espi->dev, "%s, operating frequency Error\n", __func__); + return -EOPNOTSUPP; + } + + /* IO mode supported by master */ + info = ESPI_GET_IO_MODE(master_cap_reg); + switch (info) { + case IO_MODE_QUAD: + master->caps.io_mode_quad = 1; + fallthrough; + case IO_MODE_DUAL: + master->caps.io_mode_dual = 1; + fallthrough; + case IO_MODE_SINGLE: + master->caps.io_mode_single = 1; + break; + default: + dev_err(amd_espi->dev, "%s, IO Mode Error\n", __func__); + return -EOPNOTSUPP; + } + + /* Number of slaves */ + master->caps.no_of_slaves = ESPI_GET_NO_OF_SLAVES(master_cap_reg); + + /* PC channel max payload size */ + master->caps.pc_ch_max_payload_size = ESPI_GET_MAX_PAYLOAD_PC(master_cap_reg); + + /* Flash access channel max payload size */ + master->caps.flash_ch_max_payload = ESPI_GET_MAX_PAYLOAD_FLASH(master_cap_reg); + + /* OOB message channel maximum payload size */ + master->caps.oob_ch_max_payload = ESPI_GET_MAX_PAYLOAD_OOB(master_cap_reg); + + /* Maximum virtual wire count */ + master->caps.vw_ch_max_count = ESPI_GET_MAX_PAYLOAD_VW(master_cap_reg); + + /* Alert mode support by master */ + master->caps.alert_mode = ESPI_GET_ALERT_MODE(master_cap_reg); + + /* CRC support by master */ + master->caps.crc_check_support = ESPI_GET_CRC_SUPPORT(master_cap_reg); + + return CB_SUCCESS; +} + +static void amd_espi_set_def_initial_config(struct espi_master *master, struct config *dev_conf) +{ + dev_conf->channel_mode = CHANNEL_MODE_PC; + dev_conf->io_mode = IO_MODE_SINGLE; + dev_conf->op_freq = SLAVE_OP_FREQ_16; +} + +static void amd_espi_control_reg_init(struct amd_espi *amd_espi) +{ + u32 espi_version, reg_val; + + /* Clear any existing active bits */ + reg_val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_RX_VW_REG); + writel((reg_val | ESPI_RXVW_CLR_MASK), (ESPI_BASE + AMD_ESPI_SLAVE0_RX_VW_REG)); + + /* Check eSPI version */ + espi_version = readl(ESPI_BASE + AMD_ESPI_MASTER_CAP_REG); + espi_version = ESPI_GET_ESPI_VERSION(espi_version); + + /* + * Watchdog enable and wait state control enable. + * Set wait state counter to 0x3F. + */ + reg_val = readl(ESPI_BASE + AMD_ESPI_GLOBAL_CNTRL_REG0); + reg_val = reg_val | BIT(0) | BIT(1) | + (ESPI_WAIT_STATE_COUNTER << ESPI_WAIT_STATE_COUNTER_SHIFT); + writel(reg_val, (ESPI_BASE + AMD_ESPI_GLOBAL_CNTRL_REG0)); + + /* + * Set slave0 error interrupt enable[19:0] + * Register command interrupt enable[31:24] + */ + reg_val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_INT_EN_REG); + writel(reg_val | ESPI_ALL_ERR_INT | ESPI_ALL_REG_CMD_INT, + (ESPI_BASE + AMD_ESPI_SLAVE0_INT_EN_REG)); + + /* Set eSPI controller error interrupt mapping, default is SMI (1Fh) */ + reg_val = readl(ESPI_BASE + AMD_ESPI_GLOBAL_CNTRL_REG1); + reg_val = ESPI_RGCMD_INT(amd_espi->irq, reg_val) | + ESPI_ERR_INT(ESPI_INT_SMI, reg_val); + writel(reg_val, (ESPI_BASE + AMD_ESPI_GLOBAL_CNTRL_REG1)); + + /* + * Set the IRQ mask bit and polarity. Unmask IRQ 0~23. + * Enable to configure the VW index/data register + */ + reg_val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_VW_MISC_CNTRL_REG); + reg_val &= ~(GENMASK(31, 8)); + writel((reg_val | GENMASK(3, 0)), (ESPI_BASE + AMD_ESPI_SLAVE0_VW_MISC_CNTRL_REG)); + + /* eSPI bus master enable */ + reg_val = readl(ESPI_BASE + AMD_ESPI_GLOBAL_CNTRL_REG1); + if (!(reg_val & ESPI_BUS_MASTER_EN)) { + reg_val |= ESPI_BUS_MASTER_EN | BIT(21); + writel(reg_val, (ESPI_BASE + AMD_ESPI_GLOBAL_CNTRL_REG1)); + } +} + +static int amd_espi_set_initial_config(struct amd_espi *amd_espi) +{ + struct espi_master *master = amd_espi->master; + u32 espi_initial_mode, reg_val; + struct config espi_dev_conf; + int ret; + + /* Clearing all the interrupts */ + amd_espi_clr_all_intr(amd_espi); + + espi_initial_mode = readl(ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG); + espi_initial_mode |= ((CNTRL_SLAVE0_OP_FREQ_16 << ESPI_CNTRL_SLAVE0_FREQ_SHIFT) | + (IO_MODE_SINGLE << ESPI_CNTRL_SLAVE0_IO_SHIFT)); + + if (amd_espi->master->caps.alert_mode == 1) + espi_initial_mode |= ESPI_CNTRL_SLAVE0_ALERT_MODE; + + if (amd_espi->master->caps.crc_check_support == 1) + espi_initial_mode |= ESPI_CNTRL_SLAVE0_CRC_CHECK_EN; + + writel(espi_initial_mode, (ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG)); + + /* Unmask IRQ 0~23 */ + reg_val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_VW_MISC_CNTRL_REG); + reg_val &= ~(GENMASK(31, 8)); + writel((reg_val | GENMASK(3, 0)), (ESPI_BASE + AMD_ESPI_SLAVE0_VW_MISC_CNTRL_REG)); + + amd_espi_set_def_initial_config(master, &espi_dev_conf); + + ret = amd_espi_set_general_conf(amd_espi, &espi_dev_conf); + if (ret != CB_SUCCESS) + return ret; + + amd_espi_clr_all_intr(amd_espi); + + return CB_SUCCESS; +} + +static int amd_espi_init_slave(struct amd_espi *amd_espi) +{ + struct espi_master *master = amd_espi->master; + u32 slave_caps, reg_val; + int ret; + + ret = amd_espi_get_master_cap(amd_espi, master); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Get master capability failed\n"); + return -EOPNOTSUPP; + } + + ret = amd_espi_set_initial_config(amd_espi); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "eSPI set initial config failed\n"); + return ret; + } + + ret = amd_espi_inband_reset(amd_espi); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "In-band reset failed!\n"); + return ret; + } + + ret = amd_espi_get_general_config(amd_espi, &slave_caps); + if (ret != CB_SUCCESS) + return ret; + + reg_val = readl(ESPI_BASE + AMD_ESPI_GLOBAL_CNTRL_REG1); + writel(reg_val | BIT(20), (ESPI_BASE + AMD_ESPI_GLOBAL_CNTRL_REG1)); + + if (amd_espi_setup_periph_channel(amd_espi, slave_caps) != CB_SUCCESS) { + dev_err(amd_espi->dev, "Peripheral channel setup failed\n"); + return -EOPNOTSUPP; + } + + if (amd_espi_setup_vw_channel(amd_espi, slave_caps) != CB_SUCCESS) { + dev_err(amd_espi->dev, "Virtual wire channel setup failed\n"); + return -EOPNOTSUPP; + } + + return CB_SUCCESS; +} + +static int amd_espi_suspend(struct device *dev) +{ + return 0; +} + +static int amd_espi_resume(struct device *dev) +{ + struct amd_espi *amd_espi = dev_get_drvdata(dev); + int ret; + + ret = amd_espi_set_initial_config(amd_espi); + if (ret != CB_SUCCESS) + dev_err(amd_espi->dev, "espi_set_initial_config in %s failed!\n", __func__); + + return ret; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(amd_espi_pm_ops, amd_espi_suspend, amd_espi_resume); + +static int amd_espi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct config *espi_dev_conf; + struct amd_espi *amd_espi; + struct resource *res; + int ret; + + amd_espi = devm_kzalloc(dev, sizeof(struct amd_espi), GFP_KERNEL); + if (!amd_espi) + return -ENOMEM; + + amd_espi->master = devm_kzalloc(dev, sizeof(struct espi_master), GFP_KERNEL); + if (!amd_espi->master) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EOPNOTSUPP; + + amd_espi->io_remap_addr = devm_ioremap_resource(dev, res); + if (IS_ERR(amd_espi->io_remap_addr)) { + ret = PTR_ERR(amd_espi->io_remap_addr); + return dev_err_probe(dev, ret, "ioremap of eSPI registers failed\n"); + } + + ret = amd_espi_device_create(amd_espi, dev); + if (ret != 0) + return dev_err_probe(amd_espi->dev, ret, "device creation failed\n"); + + platform_set_drvdata(pdev, amd_espi); + + /* Allocate mem for espi_device */ + espi_dev_conf = devm_kzalloc(dev, sizeof(struct config), GFP_KERNEL); + if (!espi_dev_conf) { + ret = -ENOMEM; + goto espidev_free; + } + + amd_espi->irq = platform_get_irq(pdev, 0); + if (amd_espi->irq < 0) { + ret = amd_espi->irq; + goto espidev_free; + } + + amd_espi_control_reg_init(amd_espi); + ret = amd_espi_init_slave(amd_espi); + if (ret != CB_SUCCESS) + goto espidev_free; + + dev_info(dev, "AMD ESPI device initialization completed\n"); + + return 0; + +espidev_free: + amd_espi_device_remove(amd_espi); + return ret; +} + +static void amd_espi_remove(struct platform_device *pdev) +{ + struct amd_espi *amd_espi = platform_get_drvdata(pdev); + + amd_espi_device_remove(amd_espi); +} + +#ifdef CONFIG_ACPI +static const struct acpi_device_id espi_acpi_match[] = { + { "AMDI0070", AMD_ESPI_V1 }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, espi_acpi_match); +#endif + +static struct platform_driver amd_espi_driver = { + .driver = { + .name = "amd_espi", + .owner = THIS_MODULE, + .acpi_match_table = ACPI_PTR(espi_acpi_match), + .pm = pm_sleep_ptr(&amd_espi_pm_ops), + }, + .probe = amd_espi_probe, + .remove = amd_espi_remove, +}; + +module_platform_driver(amd_espi_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("AMD eSPI Controller Driver"); diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c new file mode 100644 index 000000000000..4e46c30d3405 --- /dev/null +++ b/drivers/spi/espi-amd-dev.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD eSPI controller driver - device file operations + * + * Copyright (c) 2025, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Authors: Krishnamoorthi M + * Akshata MukundShetty + */ +#include +#include +#include +#include +#include +#include +#include + +#include "espi-amd.h" +#include "espi-amd-slave.h" + +#define ESPI_DEV_MINORS 0 +#define N_ESPI_MINORS 1 + +static LIST_HEAD(device_list); +static DEFINE_MUTEX(device_list_lock); + +static struct class *amd_espi_dev_class; +static struct cdev cdev; + +static int amd_espi_open(struct inode *inode, struct file *filp) +{ + struct amd_espi *espi; + int status = -ENXIO; + + guard(mutex)(&device_list_lock); + + list_for_each_entry(espi, &device_list, device_entry) { + if (espi->dev_minor == inode->i_rdev) { + status = 0; + break; + } + } + if (status) + goto err_dev_find; + + espi->users++; + filp->private_data = espi; + nonseekable_open(inode, filp); + +err_dev_find: + return status; +} + +static int amd_espi_release(struct inode *inode, struct file *filp) +{ + struct amd_espi *espi; + + guard(mutex)(&device_list_lock); + espi = filp->private_data; + filp->private_data = NULL; + espi->users--; + if (!espi->users && !espi->dev) + kfree(espi); + + return 0; +} + +static const struct file_operations amd_espi_fops = { + .owner = THIS_MODULE, + .open = amd_espi_open, + .release = amd_espi_release, +}; + +int amd_espi_device_create(struct amd_espi *amd_espi, struct device *dev) +{ + int ret; + + INIT_LIST_HEAD(&amd_espi->device_entry); + ret = alloc_chrdev_region(&amd_espi->dev_minor, 0, ESPI_DEV_MINORS, "amd_espi"); + if (ret < 0) { + dev_err(amd_espi->dev, "Device numbers allocation failed: %d\n", ret); + return ret; + } + + amd_espi_dev_class = class_create("amd_espi"); + if (IS_ERR(amd_espi_dev_class)) { + dev_err(amd_espi->dev, "Class creation failed\n"); + ret = PTR_ERR(amd_espi_dev_class); + goto espi_unregister_chrdev; + } + + cdev_init(&cdev, &amd_espi_fops); + ret = cdev_add(&cdev, amd_espi->dev_minor, N_ESPI_MINORS); + if (ret) + goto espi_class_cleanup; + + amd_espi->dev = dev; + dev = device_create(amd_espi_dev_class, NULL, amd_espi->dev_minor, &amd_espi, "amd_espi"); + if (IS_ERR(dev)) { + dev_err(amd_espi->dev, "Device creation failed\n"); + ret = PTR_ERR(dev); + goto espi_del_dev; + } + + list_add(&amd_espi->device_entry, &device_list); + + return 0; + +espi_del_dev: + cdev_del(&cdev); + +espi_class_cleanup: + class_destroy(amd_espi_dev_class); + +espi_unregister_chrdev: + unregister_chrdev_region(amd_espi->dev_minor, ESPI_DEV_MINORS); + return ret; +} + +void amd_espi_device_remove(struct amd_espi *amd_espi) +{ + list_del(&amd_espi->device_entry); + device_destroy(amd_espi_dev_class, amd_espi->dev_minor); + cdev_del(&cdev); + class_destroy(amd_espi_dev_class); + unregister_chrdev_region(amd_espi->dev_minor, ESPI_DEV_MINORS); +} diff --git a/drivers/spi/espi-amd-err.h b/drivers/spi/espi-amd-err.h new file mode 100644 index 000000000000..d2d3967a3c6d --- /dev/null +++ b/drivers/spi/espi-amd-err.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD eSPI controller driver error codes + * + * Copyright (c) 2025, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Authors: Krishnamoorthi M + * Akshata MukundShetty + */ +#ifndef AMD_ESPI_ERROR_H +#define AMD_ESPI_ERROR_H + +/* Error code bit positions */ +#define POS_BUS_TIMING 0 +#define POS_BUS_WAIT_STATE 1 +#define POS_CRC 2 +#define POS_NO_RESP 4 +#define POS_FATAL_ERR 5 +#define POS_NON_FATAL_ERR 6 +#define POS_INVALID_RESP_CODE 7 +#define POS_INVALID_CYCLE_TYPE 8 +#define POS_UNSUCCESS_CPL_RECV 9 +#define POS_ILLEGAL_RESP_TAG 10 +#define POS_ILLEGAL_RESP_LEN 11 +#define POS_OOB_DATA_LEN 12 +#define POS_PC_MSG_DATA 13 +#define POS_FLASH_DATA_LEN 14 +#define POS_PROTOCOL_ERR 15 + +/* Human-readable error strings */ +static char *espi_error_codes[] = { + "ERR 00: eSPI BUS TIMING ERROR", + "ERR 01: eSPI WAIT STATE TIMER TIMEOUT", + "ERR 02: eSPI CRC ERROR", + "", + "ERR 04: NO RESPONSE FROM SLAVE", + "ERR 05: FATAL_ERROR RESPONSE FROM SLAVE", + "ERR 06: NON_FATAL_ERROR RESPONSE FROM SLAVE", + "ERR 07: INVALID RESPONSE CODE RECEIVED", + "ERR 08: INVALID CYCLE TYPE RECEIVED", + "ERR 09: UNSUCCESSFUL COMPLETION PACKET", + "ERR 10: ILLEGAL RESPONSE TAG", + "ERR 11: ILLEGAL RESPONSE LENGTH", + "ERR 12: OOB PACKET DATA LENGTH ERROR", + "ERR 13: PC MESSAGE DATA LENGTH ERROR", + "ERR 14: FLASH PACKET DATA LENGTH ERROR", + "ERR 15: PROTOCOL ERROR", +}; +#endif diff --git a/drivers/spi/espi-amd-slave.h b/drivers/spi/espi-amd-slave.h new file mode 100644 index 000000000000..07aaad4f28aa --- /dev/null +++ b/drivers/spi/espi-amd-slave.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD eSPI slave device specific macros + * + * Copyright (c) 2025, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Authors: Krishnamoorthi M + * Akshata MukundShetty + */ +#ifndef AMD_ESPI_SLAVE_H +#define AMD_ESPI_SLAVE_H + +#define ESPI_SLAVE_GENERAL_CAPS_CFG 0x08 + +/* eSPI slave channel support */ +#define ESPI_SLAVE_PERIPH_CH_SUPP BIT(0) +#define ESPI_SLAVE_VW_CH_SUPP BIT(1) +#define ESPI_SLAVE_OOB_CH_SUPP BIT(2) +#define ESPI_SLAVE_FLASH_CH_SUPP BIT(3) + +/* eSPI slave frequency support */ +#define ESPI_SLAVE_OP_FREQ_SUPP_SHIFT 16 +#define ESPI_SLAVE_OP_FREQ_SUPP_MASK GENMASK(18, 16) +#define ESPI_SLAVE_OP_FREQ_SUPP_VAL(x) ((x) << ESPI_SLAVE_OP_FREQ_SUPP_SHIFT) +#define ESPI_SLAVE_OP_FREQ_SUPP_16_MHZ ESPI_SLAVE_OP_FREQ_SUPP_VAL(0) +#define ESPI_SLAVE_OP_FREQ_SUPP_33_MHZ ESPI_SLAVE_OP_FREQ_SUPP_VAL(2) +#define ESPI_SLAVE_OP_FREQ_SUPP_66_MHZ ESPI_SLAVE_OP_FREQ_SUPP_VAL(4) + +/* eSPI slave frequency selection */ +#define ESPI_SLAVE_OP_FREQ_SEL_SHIFT 20 +#define ESPI_SLAVE_OP_FREQ_SEL_MASK ~GENMASK(22, 20) +#define ESPI_SLAVE_OP_FREQ_SEL_VAL(x) ((x) << ESPI_SLAVE_OP_FREQ_SEL_SHIFT) +#define ESPI_SLAVE_OP_FREQ_SEL_16_MHZ ESPI_SLAVE_OP_FREQ_SEL_VAL(0) +#define ESPI_SLAVE_OP_FREQ_SEL_33_MHZ ESPI_SLAVE_OP_FREQ_SEL_VAL(2) +#define ESPI_SLAVE_OP_FREQ_SEL_66_MHZ ESPI_SLAVE_OP_FREQ_SEL_VAL(4) +#define ESPI_SLAVE_SET_OP_FREQ(conf, freq) (((conf) & ESPI_SLAVE_OP_FREQ_SEL_MASK) | (freq)) + +/* eSPI slave IO mode support */ +#define ESPI_SLAVE_IO_MODE_SUPP_SHIFT 24 +#define ESPI_SLAVE_IO_MODE_SUPP_MASK GENMASK(25, 24) +#define ESPI_SLAVE_IO_MODE_SUPP_VAL(x) ((x) << ESPI_SLAVE_IO_MODE_SUPP_SHIFT) +#define ESPI_SLAVE_IO_MODE_SUPP_SINGLE_ONLY ESPI_SLAVE_IO_MODE_SUPP_VAL(0) +#define ESPI_SLAVE_IO_MODE_SUPP_SINGLE_DUAL ESPI_SLAVE_IO_MODE_SUPP_VAL(1) +#define ESPI_SLAVE_IO_MODE_SUPP_SINGLE_QUAD ESPI_SLAVE_IO_MODE_SUPP_VAL(2) +#define ESPI_SLAVE_IO_MODE_SUPP_SINGLE_DUAL_QUAD ESPI_SLAVE_IO_MODE_SUPP_VAL(3) + +/* eSPI slave IO mode selection */ +#define ESPI_SLAVE_IO_MODE_SEL_SHIFT 26 +#define ESPI_SLAVE_IO_MODE_SEL_MASK ~GENMASK(27, 26) +#define ESPI_SLAVE_IO_MODE_SEL_VAL(x) ((x) << ESPI_SLAVE_IO_MODE_SEL_SHIFT) +#define ESPI_SLAVE_IO_MODE_SEL_SINGLE ESPI_SLAVE_IO_MODE_SEL_VAL(0) +#define ESPI_SLAVE_IO_MODE_SEL_DUAL ESPI_SLAVE_IO_MODE_SEL_VAL(1) +#define ESPI_SLAVE_IO_MODE_SEL_QUAD ESPI_SLAVE_IO_MODE_SEL_VAL(2) +#define ESPI_SLAVE_SET_IO_MODE(conf, mode) (((conf) & ESPI_SLAVE_IO_MODE_SEL_MASK) | (mode)) + +#define ESPI_SLAVE_ALERT_MODE_PIN BIT(28) +#define ESPI_SLAVE_CRC_ENABLE BIT(31) + +/* eSPI slave channel capabilities and configuration registers */ +#define ESPI_SLAVE_PERIPH_CFG 0x10 +#define ESPI_SLAVE_VW_CFG 0x20 +#define ESPI_SLAVE_OOB_CFG 0x30 +#define ESPI_SLAVE_FLASH_CFG 0x40 + +#define ESPI_SLAVE_CHANNEL_ENABLE BIT(0) +#define ESPI_SLAVE_CHANNEL_READY BIT(1) +#define ESPI_SLAVE_PERIPH_BUS_MASTER_ENABLE BIT(2) + +static inline bool espi_slave_supports_quad_io(u32 caps) +{ + u32 mode = caps & ESPI_SLAVE_IO_MODE_SUPP_MASK; + + return (mode == ESPI_SLAVE_IO_MODE_SUPP_SINGLE_QUAD) || + (mode == ESPI_SLAVE_IO_MODE_SUPP_SINGLE_DUAL_QUAD); +} + +static inline bool espi_slave_supports_dual_io(u32 caps) +{ + u32 mode = caps & ESPI_SLAVE_IO_MODE_SUPP_MASK; + + return (mode == ESPI_SLAVE_IO_MODE_SUPP_SINGLE_DUAL) || + (mode == ESPI_SLAVE_IO_MODE_SUPP_SINGLE_DUAL_QUAD); +} + +static inline bool espi_slave_supports_single_io(u32 caps) +{ + /* Single IO mode is supported by default */ + return true; +} + +static inline bool espi_slave_supports_66_mhz(u32 caps) +{ + u32 freq = caps & ESPI_SLAVE_OP_FREQ_SUPP_MASK; + return freq == ESPI_SLAVE_OP_FREQ_SUPP_66_MHZ; +} + +static inline bool espi_slave_supports_33_mhz(u32 caps) +{ + u32 freq = caps & ESPI_SLAVE_OP_FREQ_SUPP_MASK; + return freq == ESPI_SLAVE_OP_FREQ_SUPP_33_MHZ; +} + +static inline bool espi_slave_supports_16_mhz(u32 caps) +{ + u32 freq = caps & ESPI_SLAVE_OP_FREQ_SUPP_MASK; + return freq == ESPI_SLAVE_OP_FREQ_SUPP_16_MHZ; +} +#endif diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h new file mode 100644 index 000000000000..57b156fb0a05 --- /dev/null +++ b/drivers/spi/espi-amd.h @@ -0,0 +1,291 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD eSPI general macros and structures + * + * Copyright (c) 2025, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Authors: Krishnamoorthi M + * Akshata MukundShetty + */ +#ifndef AMD_ESPI_H +#define AMD_ESPI_H + +#include + +#define CB_SUCCESS 0 +#define DATA_SIZE_ROUNDOFF_4(NUM) (((NUM) + 3) & (~0x03u)) + +/* Timeouts and delay */ +#define ESPI_MSG_DELAY_MIN_US 50 +#define ESPI_RESP_MAX_TIMEOUT_US 200000 /* 200 ms */ + +/* Downstream transmit registers */ +#define AMD_ESPI_DS_HEADER_REG0 0x00 +#define AMD_ESPI_DS_HEADER_REG1 0x04 +#define AMD_ESPI_DS_HEADER_REG2 0x08 +#define AMD_ESPI_DS_DATA_REG0 0x0C + +/* Master capability and control registers */ +#define AMD_ESPI_MASTER_CAP_REG 0x2C +#define AMD_ESPI_GLOBAL_CNTRL_REG0 0x30 +#define AMD_ESPI_GLOBAL_CNTRL_REG1 0x34 +#define AMD_ESPI_MISC_CNTRL_REG0 0x38 +#define AMD_ESPI_MISC_CNTRL_REG1 0x3c + +/* Slave-0 configuration and interrupt registers */ +#define AMD_ESPI_SLAVE0_CONFIG_REG 0x68 +#define AMD_ESPI_SLAVE0_INT_EN_REG 0x6C +#define AMD_ESPI_SLAVE0_INT_STS_REG 0x70 +#define ESPI_CNTRL_SLAVE0_ALERT_MODE BIT(30) +#define ESPI_CNTRL_SLAVE0_CRC_CHECK_EN BIT(31) + +/* Slave-0 Virtual wire registers */ +#define AMD_ESPI_SLAVE0_RX_VW_REG 0x9C +#define AMD_ESPI_SLAVE0_VW_MISC_CNTRL_REG 0xA8 + +/* Slave-0 interrupt enable and status bits */ +#define ESPI_BUS_ERR_INT BIT(0) +#define ESPI_WAIT_TIMEOUT_INT BIT(1) +#define ESPI_CRC_ERR_INT BIT(2) +#define ESPI_NO_RESP_INT BIT(4) +#define ESPI_FATAL_ERR_INT BIT(5) +#define ESPI_NON_FATAL_ERR_INT BIT(6) +#define ESPI_INVALID_RESP_CODE_INT BIT(7) +#define ESPI_INVALID_CYCLE_TYPE_INT BIT(8) +#define ESPI_UNSUCCESS_CPL_RECV_INT BIT(9) +#define ESPI_ILLEGAL_RESP_TAG_INT BIT(10) +#define ESPI_ILLEGAL_RESP_LEN_INT BIT(11) +#define ESPI_RX_OOB_OVERFLOW_INT BIT(12) +#define ESPI_RX_PC_MSG_OVERFLOW_INT BIT(13) +#define ESPI_RX_FLASH_MSG_OVERFLOW_INT BIT(14) +#define ESPI_PROTOCOL_ERR_INT BIT(15) +#define ESPI_DNCMD_INT BIT(28) +#define ESPI_RXMSG_INT BIT(29) +#define ESPI_ALL_ERR_INT GENMASK(19, 0) +#define ESPI_ALL_REG_CMD_INT GENMASK(31, 24) + +/* eSPI global control register configurations */ +#define ESPI_BUS_MASTER_EN BIT(1) +#define ESPI_WAIT_STATE_COUNTER 0x3F +#define ESPI_WAIT_STATE_COUNTER_SHIFT 23 +#define ESPI_ERR_INT_MAP_SHIFT 8 +#define ESPI_ERR_INT(irq, val) ((u32)(((val) & ~(GENMASK(12, 8))) | \ + ((irq) << ESPI_ERR_INT_MAP_SHIFT))) +#define ESPI_INT_SMI 0x1f +#define ESPI_RGCMD_INT_MAP_SHIFT 13 +#define ESPI_RGCMD_INT(irq, val) ((u32)(((val) & ~(GENMASK(17, 13))) | \ + ((irq) << ESPI_RGCMD_INT_MAP_SHIFT))) +#define ESPI_RXVW_CLR_MASK 0xFFFF6F00 + +/* eSPI master capability register values */ +#define ESPI_GET_ESPI_VERSION(val) (((val) & GENMASK(6, 4)) >> 4) +#define ESPI_GET_MAX_PAYLOAD_FLASH(val) (((val) & GENMASK(9, 7)) >> 7) +#define ESPI_GET_MAX_PAYLOAD_OOB(val) (((val) & GENMASK(12, 10)) >> 10) +#define ESPI_GET_MAX_PAYLOAD_VW(val) (((val) & GENMASK(18, 13)) >> 13) +#define ESPI_GET_MAX_PAYLOAD_PC(val) (((val) & GENMASK(21, 19)) >> 19) +#define ESPI_GET_NO_OF_SLAVES(val) (((val) & GENMASK(24, 22)) >> 22) +#define ESPI_GET_FREQ(val) (((val) & GENMASK(27, 25)) >> 25) +#define ESPI_GET_IO_MODE(val) (((val) & GENMASK(29, 28)) >> 28) +#define ESPI_GET_ALERT_MODE(val) (((val) & BIT(30)) >> 30) +#define ESPI_GET_CRC_SUPPORT(val) (((val) & BIT(31)) >> 31) + +/* Channel modes */ +#define CHANNEL_MODE_FLASH BIT(0) +#define CHANNEL_MODE_OOB BIT(1) +#define CHANNEL_MODE_VW BIT(2) +#define CHANNEL_MODE_PC BIT(3) +#define CHAN_NOT_ENABLED BIT(4) + +/* + * Controller IO MODE encoding values + * 00 - Single I/O + * 01 - Dual I/O, Single I/O + * 10 - Quad I/O, Dual I/O, Single I/O + */ +#define IO_MODE_SINGLE 0x0 +#define IO_MODE_DUAL 0x1 +#define IO_MODE_QUAD 0x2 +#define ESPI_CNTRL_SLAVE0_IO_SHIFT 28 +#define ESPI_CNTRL_IO_MODE_MASK ~GENMASK(29, 28) +#define ESPI_CNTRL_SET_IO_MODE(conf, mode) (((conf) & ESPI_CNTRL_IO_MODE_MASK) |\ + ((mode) << ESPI_CNTRL_SLAVE0_IO_SHIFT)) + +/* + * Controller operating support frequency values + * 000 - 16.7 MHz + * 001 - 16.7 MHz, 33 MHz + * 011 - 16.7 MHz, 33 MHz, 66 MHz + */ +#define CNTRL_OP_FREQ_16 0x0 +#define CNTRL_OP_FREQ_33 0x1 +#define CNTRL_OP_FREQ_66 0x3 + +/* Slave0 operating frequency values */ +#define SLAVE_OP_FREQ_16 0x0 +#define SLAVE_OP_FREQ_33 0x2 +#define SLAVE_OP_FREQ_66 0x4 + +/* Slave0 operating frequency values in controller side */ +#define CNTRL_SLAVE0_OP_FREQ_16 0x0 +#define CNTRL_SLAVE0_OP_FREQ_33 0x1 +#define CNTRL_SLAVE0_OP_FREQ_66 0x2 + +#define ESPI_CNTRL_SLAVE0_FREQ_SHIFT 25 +#define ESPI_CNTRL_OP_MODE_MASK ~GENMASK(27, 25) +#define ESPI_CNTRL_SET_OP_FREQ(conf, freq) (((conf) & ESPI_CNTRL_OP_MODE_MASK) |\ + ((freq) << ESPI_CNTRL_SLAVE0_FREQ_SHIFT)) + +#define ESPI_BASE ((u8 __iomem *)amd_espi->io_remap_addr) + +/* + * enum amd_espi_versions - eSPI controller versions + * @AMD_ESPI_V1: AMDI0070 hardware version + */ +enum amd_espi_versions { + AMD_ESPI_V1 = 1, +}; + +/* eSPI commands */ +enum espi_cmd_type { + SET_CONFIGURATION, + GET_CONFIGURATION, + IN_BAND_RESET, + PERIPHERAL_CHNL = 4, + VW_CHNL, + OOB_CHNL, + FLASH_CHNL, +}; + +struct amd_espi { + void __iomem *io_remap_addr; + struct device *dev; + struct espi_master *master; + struct list_head device_entry; + dev_t dev_minor; + enum amd_espi_versions version; + unsigned int users; + int irq; + void (*suspend)(struct amd_espi *amd_espi); + void (*resume)(struct amd_espi *amd_espi); +}; + +struct master_caps { + /* Channel support by master, bits [3:0] */ + u32 periph_ch_en:1; + u32 vw_ch_en:1; + u32 oob_ch_en:1; + u32 flash_ch_en:1; + + /* eSPI version, bits [6:4] */ + u32 espi_version:3; + + /* Flash access channel max supported payload, bits[9:7] */ + u32 flash_ch_max_payload:3; + + /* OOB message channel max supported payload, bits[10:12] */ + u32 oob_ch_max_payload:3; + + /* Operating maximum virtual wire count, bits[18:13] */ + u32 vw_ch_max_count:6; + + /* Peripheral channel max supported payload, bits[21:19] */ + u32 pc_ch_max_payload_size:3; + + /* Number of slaves supported by master bits, [24:22] */ + u32 no_of_slaves:3; + + /* Operating frequencies, bits [27:25] */ + u32 op_freq_66:1; + u32 op_freq_33:1; + u32 op_freq_16:1; + + /* IO modes bits [29:28] */ + u32 io_mode_single:1; + u32 io_mode_dual:1; + u32 io_mode_quad:1; + + /* Alert mode support by master, bit[30] */ + u32 alert_mode:1; + + /* CRC checking support by master, bit[31] */ + u32 crc_check_support:1; +} __packed; + +struct espi_master { + struct device *dev; + struct master_caps caps; +}; + +struct config { + u8 io_mode; + u8 channel_mode; + u8 op_freq; +}; + +/* TX Header and data packet */ +union espi_txhdr0 { + u32 val; + struct { + u32 cmd_type:3; + u32 cmd_status:1; + u32 slave_sel:2; + u32 rsvd:2; + u32 hdata0:8; + u32 hdata1:8; + u32 hdata2:8; + }; +}; + +union espi_txhdr1 { + u32 val; + struct { + u32 hdata3:8; + u32 hdata4:8; + u32 hdata5:8; + u32 hdata6:8; + }; +}; + +union espi_txhdr2 { + u32 val; + struct { + u32 hdata7:8; + u32 rsvd:24; + }; +}; + +union espi_txdata { + u32 val; + struct { + u32 dbyte0:8; + u32 dbyte1:8; + u32 dbyte2:8; + u32 dbyte3:8; + }; +}; + +struct espi_txcmd { + union espi_txhdr0 hdr0; + union espi_txhdr1 hdr1; + union espi_txhdr2 hdr2; + union espi_txdata *data; + u32 expected_status_codes; +}; + +/* Function prototypes */ +int amd_espi_device_create(struct amd_espi *amd_espi, struct device *dev); +void amd_espi_device_remove(struct amd_espi *amd_espi); +int amd_espi_inband_reset(struct amd_espi *amd_espi); +int amd_espi_get_general_config(struct amd_espi *amd_espi, u32 *config); +int amd_espi_set_general_conf(struct amd_espi *amd_espi, struct config *dev); +int amd_espi_set_config(struct amd_espi *amd_espi, u32 config, u16 slave_reg_address); +int amd_espi_set_iomode(struct amd_espi *amd_espi, u32 *slave_config, u32 *ctrlr_config, + u8 io_mode); +int amd_espi_set_freqmode(struct amd_espi *amd_espi, u32 *slave_config, u32 *ctrlr_config, + u8 op_freq); +int amd_espi_get_channel_config(struct amd_espi *amd_espi); +int amd_espi_setup_periph_channel(struct amd_espi *amd_espi, u32 slave_caps); +int amd_espi_setup_vw_channel(struct amd_espi *amd_espi, u32 slave_caps); +void amd_espi_clr_all_intr(struct amd_espi *amd_espi); +#endif From patchwork Thu Mar 13 18:34:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015776 Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on2066.outbound.protection.outlook.com [40.107.96.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 18DC01EFF89; Thu, 13 Mar 2025 18:35:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.96.66 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890925; cv=fail; b=SPfEnS8Cj089mRCgAlTvdnpjakkoO8P9uu/10MqwCPsmgT0/ltuze5ZGryooIyC53I4gHdHRyby92Mqp+xPd0hPr1MOTjnlfznmS8wileatNv6cb2YaNbRSTNllqW7DqvVr43RxwgpJpaAWdwdJsLoVQj+bh73ILsu+1zx4Jufo= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890925; c=relaxed/simple; bh=SDOhMpvv5CUWxLc4n+Mtd2YfN7WjD53fJtdJiqRpVso=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RtPHY5z212+GTsPY1Ax+0IhxUUFUQFOCuLsYhcea3b6cr5vzMHqYgL9vnGcED7JJYqNhw+kJMvM1lYqzPWIYdNvm2nXB7VfdM6v10zG/2KuP+j4wn4hBgNkrIjRwmpoJQqt3p4ibeuHTFAxs64S8Ww6XS3acpUbrkM9kSukOvNM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=cDrQGblk; arc=fail smtp.client-ip=40.107.96.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="cDrQGblk" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=mHH0JK2jfNupzqCzGnQ/2tmhpEY8Ncf3HQtI0qBXyVW0g4UEBzAHU4wP6u8ZburhukTQc+Sf2j7+Mxl8XHarA+bSIy67E/QQulWzlXqdYwSb6vY34QhTnmeGNVBPrtwTkSHDzxYxRlaAlSJsNQC8+WL+R9bXlyjAblTvcLh+DZG4/z4uJVfAQm8M45mo3MCDe+KbxtBqfQYmxlrUUWFIT0xyBvOKVCNx50qVbbtjvAdmTBAnwEKMFPTw/YAIRNfUPlqnNb94uHISeM5dqg19rg7YNmVezmFylEZXkHKOfImBVpedm9WZZXuzpk3WbPH6ulrczYFQErD5uD/27Y1njw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Dv14Kbfg9WAS3y5Hg+bwFR79F6jjD+TByaxPf6LLv9M=; b=HEN/4N+HwKdWiRUziiYI0b9C+D8wIAYIJNfkHLuLQjVnZ8F4F4KQh6THyEj42/cYvL5R3bXAz4ZwnzpbD8IJYai94JgfhSd8V7W0tVC5XEfebfy3vC/fY/vzJvEB76jGTnjPqif1jaxbe1l9O7Go4i8NSkMAup1IM+lraCe+vq66mk1emVZWCJlrnJOE13+3Au2Q2lHHhoGIADRSfFZ09CCTfkW9GSG4E9oTT9KENaBMnWbB/uKXW6L3tRMX02BhfFdncGJ3LLARDwQ67JpH5VGnMP1K2NDHOvuKOlceN4xNnZAhd9xkcg+A3OqBK3UjcFFJmLrBbkrAnBLFEZMiQw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Dv14Kbfg9WAS3y5Hg+bwFR79F6jjD+TByaxPf6LLv9M=; b=cDrQGblkrfJC4gE0IwU5XW6fx1UXS+S9xs1cEfn7P3BnqCIVsAFjJ3zDRW4wYTNKOZfNHHr3deJaPGaivcYGcEbt3RXwiZlAeVkkQjntaDJPBLbFCtn8FrkP4W/jdgRGlrS+1yKFO8TtuKZJWTVwabt0bgAMob5N9dq1uG2OigA= Received: from SA0PR11CA0210.namprd11.prod.outlook.com (2603:10b6:806:1bc::35) by SJ0PR12MB6830.namprd12.prod.outlook.com (2603:10b6:a03:47c::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 18:35:18 +0000 Received: from SN1PEPF000397B3.namprd05.prod.outlook.com (2603:10b6:806:1bc:cafe::c1) by SA0PR11CA0210.outlook.office365.com (2603:10b6:806:1bc::35) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.26 via Frontend Transport; Thu, 13 Mar 2025 18:35:18 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B3.mail.protection.outlook.com (10.167.248.57) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:35:17 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:35:15 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 02/10] spi: espi_amd: Add eSPI set config IOCTL command Date: Fri, 14 Mar 2025 00:04:32 +0530 Message-ID: <20250313183440.261872-3-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B3:EE_|SJ0PR12MB6830:EE_ X-MS-Office365-Filtering-Correlation-Id: 6f5082b9-c418-447d-f0c5-08dd625dcdb8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|1800799024|376014; X-Microsoft-Antispam-Message-Info: Ho2/5ErI5Nja8+HdZvEWbcD2zY6S1Ppd2ra8biadYjCvWlpq0+ayfylY7je19nvwzI7cZFX6w7yqsfsVXhK++WtXL9a+Tif11ugIbDDPWblJDq1ogBs4yttjqnVUQ48EhS+sXvAxzNYI1qMBXJPTRyQAWJ9fq7O/9uXAfvK0HBY5bfFXxilvLVc6aBPhLleqP6OauNFoOh30G6WJxfx4sdLnxMaGog5AmoZpZ8AUywbJaSLbtZ2bI0cygP4SMlhp6hGFhKOfgyfWfz9u0SHE0KsEVD9jjgX0zPyiqnWQdOjj+HeYk12FslyN9T1zoPBDR16xg7BsDdHw9+MipkSoZjkFNsgxPzCath/oDDBhVdPsKPcf0wY1tKu1XwQTMEJG3gJJSxOPJaTeOrx3m/bdKJPoO9PGJoIRWzjVaU03ISWL3nJG2wloEAtOdooRAnSJjnPXsJxa3CLIVnxNgontQ+AC9vZ6H3V2GwES3WkVpzzI+D3HnB1SOi6EgdhY9+xUxOUXkqPxmhbZWb8irPia/EU2MHW6/elp6yL5+0U4QGwuP6nj1ww6P3MtMZFwp54xuVWFEIOY7rqBzWFF7aUqAChCLl5a2wivVe9/61FLQT5pDDhPPKYN9jDPY4gtZAfbbfthkj8C84cXJ/D5RtP6SWurx2XzbMqSQIfKiRIwbGIyOlsaqlcSCRPWruSgGC1MGMhgkVGsa6qaaMOWu81MhwdVdhE6XJaQTW/+QCAupepqBgVkJULP8WDbK2K/wpzbJARwSWG/OxArox7ATP+EgTpXoX+NL7w+rDERJYwgI3TYo0dBt/LXcT6GYpryhjc9uKsWwTxMPpHJQrKZiVVWEj5o0Ftxru14TOSHO0a/M56RslItVtGf3rQ1c0T8bQmDrzoiMHVqPS+6oRTEmCbUVDDZSViGqgyCpcpAyPaeqPX+m8njUC8IxVbIyIO5sGyUAo7vTnakirrtZrEMWrSbvbV44J6wetvmM/TaAXNZVrI+3aY/tvmMMufCoLBBNINEKyXLj0nD9Dd3ZV72eFDctAVPVn0Lw9CffvWD1WS2ISSIDNbc1HAp0XNcLM+lfP5X5pTg5e12pvMQprm4C+IjQgi1OzcwpADZrz5ywuLOU6NXozE4TSJSXDOp8dpO7VcdKAs6wpgLQLRB2J+TtQnlfuHG9vmaKPO1kjoZsfj4T0DGZf3M8a5Ph+DpUR5TDA7bH1pQm1JNBKoSn7KxjoP+QPUOrH4lo/x14+gsc1ODj+ntL4oxb8QinTweIsuEHNjDhVnnxKqDNHEHDVlwCfgd0nXvfgHOJv88NCakUeY3BEXDxY+bkkO6fKh048gDEoMS5+wO3Xu34iFyXgWErlx+FlM1UTn0oX8zOsn1COHGt19qFIHP9ZEGufPCxQ5v0ELbHt/luF/UpOKs09VRnz9mjMbVTmN4mqHfdUHGSNeIRrNUIkDWgoQgKAqgdWRtxINlkSCsOoRupBDr5718sF4x6g== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:35:17.8783 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 6f5082b9-c418-447d-f0c5-08dd625dcdb8 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B3.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR12MB6830 This patch introduces an IOCTL command to set the configuration of the eSPI controller and eSPI slave0. The configuration options include parameters like frequency, channel, and IO mode. The new IOCTL command allow users to dynamically configure the eSPI controller and slave. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-dev.c | 94 ++++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd.h | 4 ++ 2 files changed, 98 insertions(+) diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index 4e46c30d3405..5f25ad2b1eef 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -28,6 +28,99 @@ static DEFINE_MUTEX(device_list_lock); static struct class *amd_espi_dev_class; static struct cdev cdev; +static int amd_espi_ioctl_set_conf(struct amd_espi *amd_espi, unsigned long arg) +{ + struct config *dev_conf, *config; + u32 slave_config; + int ret; + + dev_conf = kzalloc(sizeof(*dev_conf), GFP_KERNEL); + if (!dev_conf) + return -ENOMEM; + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) { + kfree(dev_conf); + return -ENOMEM; + } + + if (copy_from_user(config, (void __user *)arg, sizeof(struct config))) { + ret = -EFAULT; + goto set_config_free; + } + + /* IO mode configuration */ + if (config->io_mode != IO_MODE_SINGLE && config->io_mode != IO_MODE_DUAL && + config->io_mode != IO_MODE_QUAD) { + dev_err(amd_espi->dev, "Invalid IO mode\n"); + ret = -EOPNOTSUPP; + goto set_config_free; + } else { + dev_conf->io_mode = config->io_mode; + } + + /* Set operating frequency configuration */ + if (config->op_freq != SLAVE_OP_FREQ_16 && config->op_freq != SLAVE_OP_FREQ_33 && + config->op_freq != SLAVE_OP_FREQ_66) { + dev_err(amd_espi->dev, "Invalid operating frequency\n"); + ret = -EOPNOTSUPP; + goto set_config_free; + } else { + dev_conf->op_freq = config->op_freq; + } + + ret = amd_espi_set_general_conf(amd_espi, dev_conf); + if (ret != CB_SUCCESS) + goto set_config_free; + + /* Set channel configuration */ + ret = amd_espi_get_general_config(amd_espi, &slave_config); + if (ret != CB_SUCCESS) + goto set_config_free; + + if (config->channel_mode == CHANNEL_MODE_PC) { + ret = amd_espi_setup_periph_channel(amd_espi, slave_config); + if (ret) { + dev_err(amd_espi->dev, "Peripheral channel setup failed\n"); + goto set_config_free; + } + } else if (config->channel_mode == CHANNEL_MODE_VW) { + ret = amd_espi_setup_vw_channel(amd_espi, slave_config); + if (ret) { + dev_err(amd_espi->dev, "Virtual wire channel setup failed\n"); + goto set_config_free; + } + } else { + ret = -EOPNOTSUPP; + } + +set_config_free: + kfree(dev_conf); + kfree(config); + return ret; +} + +static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct amd_espi *amd_espi = filp->private_data; + int ret = 0; + + /* Check type and command number */ + if (_IOC_TYPE(cmd) != ESPI_MAGIC_NUMBER) + return -EINVAL; + + switch (cmd) { + case ESPI_SET_CONFIG: + ret = amd_espi_ioctl_set_conf(amd_espi, arg); + break; + default: + dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); + ret = -EINVAL; + } + + return ret; +} + static int amd_espi_open(struct inode *inode, struct file *filp) { struct amd_espi *espi; @@ -68,6 +161,7 @@ static int amd_espi_release(struct inode *inode, struct file *filp) static const struct file_operations amd_espi_fops = { .owner = THIS_MODULE, + .unlocked_ioctl = amd_espi_ioctl, .open = amd_espi_open, .release = amd_espi_release, }; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index 57b156fb0a05..1de53426059b 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -138,6 +138,10 @@ #define ESPI_BASE ((u8 __iomem *)amd_espi->io_remap_addr) +/* IOCTL calls */ +#define ESPI_MAGIC_NUMBER 'i' +#define ESPI_SET_CONFIG _IOW(ESPI_MAGIC_NUMBER, 0x1, struct config) + /* * enum amd_espi_versions - eSPI controller versions * @AMD_ESPI_V1: AMDI0070 hardware version From patchwork Thu Mar 13 18:34:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015777 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2056.outbound.protection.outlook.com [40.107.236.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3898A1F12EB; Thu, 13 Mar 2025 18:35:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.236.56 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890928; cv=fail; b=PzL5BM19Bwr4Zk7KTP4fA0dt8B8QpW2+elzPdHgZAwiYZw15LrUPH3WflmMc6+KDUxFJLYDtlW1iYyiszw0nO9pNXXwoTOeklQFQimmeumcWtEOugUQr5e6vUokVIrv+t9Moopp5BUYBrcfBIVYM/NCJRFuvZZsVP800SERCVKE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890928; c=relaxed/simple; bh=WvQbbq7ty/Jjn47sm0wQduOqpRPbb4cBD57nl/RcfAc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=U+GhwbaqiA7gPv1VA+dn4+yPt9HbL5LazlROOIHrFWmo8bJYe24WR7vI/9dtdWGR+iDYYwGcFYlH0hoMapn4jJuL17ys9pF8JPP/texteg9ShhXsPqZOHgwJY7sOTo6pe/dtkI8kXMS3DXsbk4Bfxr1m/6gJG6H8RzvExI1Sg1Y= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=qCy04Y1w; arc=fail smtp.client-ip=40.107.236.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="qCy04Y1w" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=a6gOvY0e2pC2ouUMCYakXJHR/d4AG8jMfw3AUiWr7mGEivh9007h2sUBGcNNe+RJ7+Sj+rouB43Ljinbk7hR4PM3KNWfmdnzJxUfPLGlQG+5w7sjnhCcb9/dNdfXLqbmOP/MnXFZcdzzONwz1iriuW16JPNYx6JSy61mvpXwv4C8JmCY5zIa6201c2OruUsXiaQE9QHL3tM2QdMzwU3c1nty+rky4eo3XMnyp4/1rXpgU0h+5ZuA5URV4M8OdrZ3k7bknB0NQqPhZ7bV5Ra+0OILVLVGo6JtEDuJJ3V8HnVfgBf1Ala4r91x/o5omfk87vbipyodknYkTBY0QRO/Ow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=XcmMzMTVNOg/FuNrokoqPJudv6bOErcQ+qpNd7xpllI=; b=Q0pfqABF2DnPcFTBfbkPfOatYVYUqYnLlQD/AP4Y3U4eRQAX2xa9wojrWClfmSfJE2FDfVFnSrUHjo+5A2flKVV0zSvAnK+zg3vrADHHkSZHed+K5B5NJh8gfXzj1DuBPn5KyDIlvEIvZM6gWieCSomQmsyY9U4MbFXMm5gNmnC7H6a2GQ5AnV/I1V+MKz/SM5fvz28W5cTbsFWT8i24l41T34UKleHTAPvbQdaDwgjWinSekNZdFVZ/IPBlJAnwK6BJ38QQ7jjFJw3j7hIsPvNeKrSYJ30MUqCdXm/QJfvfhUAxuMCwtkaFxwnkf96mwZf/4wZNKGTcp2fWpolHog== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XcmMzMTVNOg/FuNrokoqPJudv6bOErcQ+qpNd7xpllI=; b=qCy04Y1whQE6QkQ2J8v5CPmRjV8Bpotf6NtjosHXkThIWPsTAA1xzlmrmgL8YV1n56nF/bd6eQYsUV0C9UWO4uUiylgp+ZbJ8v/pyh01oxYX7bqhsoPgAaE/LX6dGBi6dC8bXg38CJksZ2q1So2d5TsXqnrR2MPmGD37f/MV+eI= Received: from SA1P222CA0114.NAMP222.PROD.OUTLOOK.COM (2603:10b6:806:3c5::21) by PH7PR12MB8055.namprd12.prod.outlook.com (2603:10b6:510:268::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 18:35:21 +0000 Received: from SN1PEPF000397B5.namprd05.prod.outlook.com (2603:10b6:806:3c5:cafe::e1) by SA1P222CA0114.outlook.office365.com (2603:10b6:806:3c5::21) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.27 via Frontend Transport; Thu, 13 Mar 2025 18:35:21 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B5.mail.protection.outlook.com (10.167.248.59) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:35:21 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:35:18 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 03/10] spi: espi_amd: Add eSPI get config IOCTL command Date: Fri, 14 Mar 2025 00:04:33 +0530 Message-ID: <20250313183440.261872-4-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B5:EE_|PH7PR12MB8055:EE_ X-MS-Office365-Filtering-Correlation-Id: 0449a52d-1bb6-40a6-62bd-08dd625dcfd0 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|82310400026|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: LZ4HY1/VaA4guU4iQE3d2qg8lB+Rhv8ax8PfKAHWigUkvDV3e/OaCuFhqQV4tMh7t7VUjQ/bf5vWjC4y27c4Zv/9xHwLtnrtn+osfaR1T84AjpGlD4gFaIFO3Ydim5yzeeD95ZFta9Mng4UHeej/4JZj1BtFuTk2tiFDv45dXPdm2J58J8AaidQzcFWoJbYT4kxyU+hddne8gjk+MBcsgmj/dHSl6Jo2zUfH5ettSmyyHNFB1PyTM/2asl3/48nyStWkdWL+16IR6LB7O9KHP14vlvgBSlX0loro5EgDfWRors2pSYIqtNtFbHgTiEPlCmzeiJYeN9yu9gaxynjWBfLvwl0zLLxVIxiOMgjMomZ7JF44v1sjZOQAyaqbSBGNiIo4v2tu8rgUvCLcbR+kXrtKYyD//M0YZv+aa9CfC9JfjczXAnPAgKcvbKvdIzM0pkeWs63FNRmOgqgG23W0YzRJ7TNeUGbUDhrPTLHE7PwcYR3MS26VQ6kZXt/IOmlJ7UbGfJUBB17lOAWiMzsvloMNCerqO38KH3O27zN1ud4fMxuVVJ9sX+Y7fNUf+zYF45cYERhIGa63Yf7/mOH2x5NrCvr3jtHKDCOPjSwQHvrspHGiZllZ8FhIzem6Pnj9LctbLG7jKc7FJqEg7eLrlDoFvugmYrKo9la8bnM369zp24MiELbdcyoKhkK0+IuJkiQufrxjJkKXNOXfWkcRMlSLoVgvlPmjVyi4zGrTWl+1PoljlAoxAjprTe/sq+QvgK9naVlVT/afGak4A2XQ/UJ59n+5cEngrMguaf9TtNc3/AWmKZHOuxt8KSXynSGjfenRuC76izMwRlrBkg8hv4pJUbxoscniqBQfTM1BrWL9lOBo5hCQM1pazZE1Sp+0rgACPFaEs3JVjhQFbRp+BP7zV26dAEdiIo+Q62xubY////vtc3ROpEgqnGM4bmNXmORyKTGcH/YQ47PNViTI27fMoc0ctmZS7/keF7smkYFzp9V0l4Z/4mjycX4kOxkjbPdH0IFH8GuFc8VtNHjPyqWaULKIKN0GAeDfRMR1GCQzUYXmL29ZjJyoSgodLU0sZfboVZZvmWEUax5WNspF0boPtSRjrjQoITRLIqRY+leVVx3y7A5uE7MkLsBTIi59hCLGtzUyz9l+r5FY/rVcE//D7zuGVOsgOJmMGGwcYo+eovqRi96Ius/nDUx8n+KluTgac+KVcbZ7k8dQ+MC1LXvHgHCDEYPTrn8oKGyZhCNxsKujObU6NI62V54j6/vnY3Jx/NZtgY621irCpVNX80c/1mIulgSbzy7V7foBTfSouitrvJf+Yd9vLS4CCjTWKQwYbBpzlu5qPQqXipijWtZ/cx0WaTfB9BLulmbzLEkDRJxG2ZeQK760CcANSJ9Qdkn1fpEfICfMIYCJCRwL4FFuBskp7CqDiZkvapWkKbtImujdDNJOLwUX8svEEZXLbOgF6397NSCvjJsKzCt2CA== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(82310400026)(36860700013)(1800799024);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:35:21.3093 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 0449a52d-1bb6-40a6-62bd-08dd625dcfd0 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B5.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB8055 This patch introduces an IOCTL command to retrieve the configuration of the eSPI controller and eSPI slave0. The configuration parameters include the frequency, channel, and IO mode. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-dev.c | 69 ++++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd.h | 1 + 2 files changed, 70 insertions(+) diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index 5f25ad2b1eef..79224f4f86fa 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -100,6 +100,72 @@ static int amd_espi_ioctl_set_conf(struct amd_espi *amd_espi, unsigned long arg) return ret; } +static int amd_espi_ioctl_get_conf(struct amd_espi *amd_espi, unsigned long arg) +{ + u32 op_freq, io_mode, slave_conf; + struct config *config; + int ret; + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) + return -ENOMEM; + + ret = amd_espi_get_general_config(amd_espi, &slave_conf); + if (ret != CB_SUCCESS) + goto get_config_free; + + /* Get IO mode configuration */ + io_mode = (slave_conf & GENMASK(27, 26)) >> ESPI_SLAVE_IO_MODE_SEL_SHIFT; + switch (io_mode) { + case IO_MODE_SINGLE: + case IO_MODE_DUAL: + case IO_MODE_QUAD: + config->io_mode = io_mode; + break; + default: + dev_err(amd_espi->dev, "Invalid IO mode\n"); + ret = -EOPNOTSUPP; + goto get_config_free; + } + + /* Get operating frequency configuration */ + op_freq = (slave_conf & GENMASK(22, 20)) >> ESPI_SLAVE_OP_FREQ_SEL_SHIFT; + switch (op_freq) { + case SLAVE_OP_FREQ_16: + case SLAVE_OP_FREQ_33: + case SLAVE_OP_FREQ_66: + config->op_freq = op_freq; + break; + default: + dev_err(amd_espi->dev, "Invalid operating frequency\n"); + ret = -EOPNOTSUPP; + goto get_config_free; + } + + /* Get channel configuration */ + ret = amd_espi_get_channel_config(amd_espi); + config->channel_mode = 0; + + if (ret == -EOPNOTSUPP) { + config->channel_mode = CHAN_NOT_ENABLED; + } else { + if (ret & CHANNEL_MODE_PC) + config->channel_mode |= CHANNEL_MODE_PC; + if (ret & CHANNEL_MODE_VW) + config->channel_mode |= CHANNEL_MODE_VW; + } + + if (copy_to_user((void __user *)arg, config, sizeof(struct config))) { + ret = -EFAULT; + goto get_config_free; + } + ret = 0; + +get_config_free: + kfree(config); + return ret; +} + static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct amd_espi *amd_espi = filp->private_data; @@ -113,6 +179,9 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar case ESPI_SET_CONFIG: ret = amd_espi_ioctl_set_conf(amd_espi, arg); break; + case ESPI_GET_CONFIG: + ret = amd_espi_ioctl_get_conf(amd_espi, arg); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index 1de53426059b..bc15f7417c37 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -141,6 +141,7 @@ /* IOCTL calls */ #define ESPI_MAGIC_NUMBER 'i' #define ESPI_SET_CONFIG _IOW(ESPI_MAGIC_NUMBER, 0x1, struct config) +#define ESPI_GET_CONFIG _IOR(ESPI_MAGIC_NUMBER, 0x2, struct config) /* * enum amd_espi_versions - eSPI controller versions From patchwork Thu Mar 13 18:34:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015778 Received: from NAM04-BN8-obe.outbound.protection.outlook.com (mail-bn8nam04on2069.outbound.protection.outlook.com [40.107.100.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 10B391EB9F4; Thu, 13 Mar 2025 18:35:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.100.69 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890939; cv=fail; b=Pjrg8zFo8pQ5NcT5maky8R+mX6EztzweMt977Ckkb1Svqy79IMP0TPcOAiKhXJ3tqz2QnB4hz+Na8YmFEBIYoJTFKp1Qu/+bFVPUpHWO4bZyE8/OG1K3PZO17Z0dphcug1LJsB8slk56jhDq1I1cuiZlehMRpPq67NCe3/aU4K0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890939; c=relaxed/simple; bh=aNz1RDWbRXMU1F38VVZFbthlSxVb917nxXOb4UN+nYQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=e0pmPbs7PUhJaHiicC26nF9h/JoJklx8u6iumFb1GAY4VFGZsGpOuDGs7xaJW4rh9pY62VRUuK8HFKll5PbbyvYB0MgBuUCogLQUlrb/i3RsYe4c8tuE3gShuuzUPFH/7vrAVv4RDzwbFWVwPAoudo/ELIfGMZYWWVYeyI3tJ6I= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=KtstruO5; arc=fail smtp.client-ip=40.107.100.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="KtstruO5" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=KEV9TzQJ8th4P2UwXQa70Rbpptk/Sk8OZn0h1lZ5vPAItZkzozRqeqrh4ZeYtFtuMd0CFS4rdDh356JqU4BLtsCFBhW6BU6HfNY8wL1Gqst6HyILgPH/4q31LJpF92Cj3QafZa5rNkqPtrsktE5hJoPsVDYvjrDZnap2bZzkIuugpm/f+fvX6S/9V5ZgHMGMta7DEs9JBSI4ws0KDWOGn/aiu5RmPhBv/2FZuUSaNFZ5NhbJdulUHfz1unpnK9jfGvV+5ceKoBobDYqj/Z1eRUpQpz/tLOERu2AMBlNSH7K5DAab2qzrWTauxmVS04oZgczJYXKbQr7vEJijUxPeiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6qT6iUzxCKilk7BnVrJodT0718iVMqX2khfYvWglEFw=; b=pCpjfn7+IEPbofb/NRoxfCoUTsRvoz9ouR133aqpaz8urdhX2KZbmXhjCXb24Ir7706JHwArah1qlj2/lBf5Xnlhyp+fntvstDWwtGgwyiAGjjBRRQ3uH7TW3pa7yRsxSRbt2wRx/ApSeNhkzuSj/vq8pU5Fyx83CC0V7Yl3gIRqgy0GaHL2JcCy05Fmv7va88HuvIkFJqKrUg/7vlz8EVAqb86vd6opIiomxGddOK9BgiSD5MnVSS7WVNn+Wvvkgwxnd6QinXlRak+NdXoBQpTf0ByBaHQnN8wJ3fAZfZia/XBXi4VecXavaoIWb3J7kiOgYzxvGTMUm6WJn+AoTw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6qT6iUzxCKilk7BnVrJodT0718iVMqX2khfYvWglEFw=; b=KtstruO5FALJ1AXCrDcyKs8McNtFUy9fipiSRcx8HQHgZLXIwmmWyJck+uGP6+M4qecrELtneEo3UdqznAs4tYLbqNKuPDOMqDmAJ+B3pFbQNOVF82AD6wITueE48Qzr3YUMWsr2KDVuA1b2rHU3nI2eQCPS2M4cNmfPDznW4BA= Received: from SN7PR04CA0218.namprd04.prod.outlook.com (2603:10b6:806:127::13) by DS7PR12MB6024.namprd12.prod.outlook.com (2603:10b6:8:84::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8534.28; Thu, 13 Mar 2025 18:35:29 +0000 Received: from SN1PEPF000397B0.namprd05.prod.outlook.com (2603:10b6:806:127:cafe::20) by SN7PR04CA0218.outlook.office365.com (2603:10b6:806:127::13) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.28 via Frontend Transport; Thu, 13 Mar 2025 18:35:29 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B0.mail.protection.outlook.com (10.167.248.54) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:35:28 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:35:26 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 04/10] spi: espi_amd: Add eSPI inband-reset IOCTL command Date: Fri, 14 Mar 2025 00:04:34 +0530 Message-ID: <20250313183440.261872-5-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B0:EE_|DS7PR12MB6024:EE_ X-MS-Office365-Filtering-Correlation-Id: 73e49a84-df34-448a-f6b0-08dd625dd44a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|376014|82310400026; X-Microsoft-Antispam-Message-Info: ri35u7InIs85lDQiefbBXjuLHxZDesfo7WYTk6LcsQ7yRVLf0D7WZ0wdqDxGL3H3v+wWpREayRBG98X0vfTjH553qTzo1mNlKKxjK6ZoT/ZPuFMpgNx8gv3pE8LjA0cj/gbuzHG4BixFAslSCg6izr7GZdpW+5gieC33Uov9vM5U2kvnEtblGWxCHeYfTKG6pphnri7UlpeVlyqOZtnChr07MZOnnWmgGyTY1qNPOpgdVduh3oGoWWi31olpbvYQHNCF9dSpGkKNcOBUvA5+vWJiX9Hiy1Cm9ocvBLyIveYkE3nhoo2hGQyrv05C0f0N0YgEl/VKiW6Y1GKOTJ/IM+c/WS6TmK6C7sUhtpBP3RjOaXhYbg+9jDqWatb2e9N51oDyPqG/m9ZJfx4LnA5d5T0CzGicR0eBNEY1N3VsGtHGOZsA2M5K+Ajecxk1acOoQOcFbxDY6JwzG2YXtpWG/Zx57BjdxaXn4hII0W7JQioEpUs/GMWWrIig9ee3sMKWDyqSR6B570C5m5rpbw9gt1EDeB5etppAgvi2Q9T8CayIs3l6khbJmZRWPOtY26LpD9SOnxaZ9VjY4mf4LZymyX1xfgvW1xrGs+kkcJMFIgTtUn3U/uhcpFku/PCcmRumH2FBzYH1baQ7D+5d9BHOVriZofQIUnMMg1bOxUXHad1a1of6bEBXF42ULGMbs5nRoifZTJFG6X6DMtsxRt3YDBT3WC1+371G8G7ONBSN4+qExk/uwGF3UmeMoPHWDZ7eKhqDo5pgLcMiPXPykvR5cRxvrMxGcNFfB1YA0aoAbnyrmzza/KWTrDfLQ+9193+M5Qm4/PPuHGsP7naEJC5OpjLug7X3JZ2aLl5VJ5X0vFVS7xBZS42cVU59Xm3zAg1pKK8ZObwJaAHs02Ba6ya3vlYkrFWx7EO5DdYo/T42clhtMV+XHg3hyHDcyA+THw79HFGMSL9u99hPqdQTh01rz0W5M4k/LFqzzT/jpCRPfynxf/XLythKE71lfLgg9wDtWlWk3Ldbo6OSOD1lPqaYQqIBMEoM6Coc4Xv+3vgiMbeiL4ok7JwZi9Z96bT+pzqrg/diz2unx8dHJms9qn6wS9mDo1f3fHqGnA88bjwxEPRFaAXIxKy82UXXAMK/Sa7ifD4ud4g2KLtOtydWK5kNqXNDOBJlMdPfY01uOyR2NxN9lZoxmACDmUnsmKAtoUpLO/o5EFAC3z3Qw5wBNH4ONW+GSQKBAOczeTTx4El/+Q/kfy9UA+ofQapTJQVV1oQ02SGJcImOv1yl5D9o70L6Awa9pXlAkF93AdA9XsOqItlny53/0vKmxsJ1b7WulPEXxkVZe0WuY1f0z+jSvP0HD6XHS/qYV5AiQyauokl7rSPlwNONxyOdIz2rM172jM03GeGPYLxlWLBVgYSobheRTRnG82/akVryhQPk8n8Ht/tvCjrblolmAhVAKpHEHS/YAYBu8gM+bs5r4a3PNUSsTg== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(376014)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:35:28.9016 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 73e49a84-df34-448a-f6b0-08dd625dd44a X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B0.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS7PR12MB6024 This patch adds support for a channel-independent IOCTL command to dynamically reset the configuration settings of the eSPI controller. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-dev.c | 5 +++++ drivers/spi/espi-amd.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index 79224f4f86fa..ba2becdec8e6 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -182,6 +182,11 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar case ESPI_GET_CONFIG: ret = amd_espi_ioctl_get_conf(amd_espi, arg); break; + case ESPI_INBAND_RESET: + ret = amd_espi_inband_reset(amd_espi); + if (ret != CB_SUCCESS) + dev_err(amd_espi->dev, "In-band reset failed!\n"); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index bc15f7417c37..3c6e9b92c08d 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -142,6 +142,7 @@ #define ESPI_MAGIC_NUMBER 'i' #define ESPI_SET_CONFIG _IOW(ESPI_MAGIC_NUMBER, 0x1, struct config) #define ESPI_GET_CONFIG _IOR(ESPI_MAGIC_NUMBER, 0x2, struct config) +#define ESPI_INBAND_RESET _IO(ESPI_MAGIC_NUMBER, 0x3) /* * enum amd_espi_versions - eSPI controller versions From patchwork Thu Mar 13 18:34:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015779 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2065.outbound.protection.outlook.com [40.107.220.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35CF61F2BAD; Thu, 13 Mar 2025 18:35:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.65 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890944; cv=fail; b=luzieCqyzQh0ghfFWYyit+xCWPY1nf7cOCLPb4cGYrAiTv5NpcDo3ALPkxjmJxGfPZX2+4v6jzskAGAiFf911M/q6acOUPcPtoMfWIewA8OlgJGLmifelpHYwKfw6R+QDSXSW6kXkcOOTrRNR0lQl8GYIvFYuT5fXJcS91OcVns= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890944; c=relaxed/simple; bh=i1QxYbHD/e/CuDf8e2+/vBR6uwxdqYNhjckKZmuvEEs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PUp4oYmhXiKq+Y6Ga74fvljilyFwJtie8UVLJfSleDULJ93pD12vhfm7eWmNjMpmEw7pm+fOLnxZ/Wj6S/GXN3wtui6UBXTaXOQ50q41wqR/JZKi+eVU4RvRN+6VRTkneiw3OG1QTHUmqnypsr5J1F/6fRCVCHSk077dr8epdmY= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=glRM6pDA; arc=fail smtp.client-ip=40.107.220.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="glRM6pDA" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=DNbeMuN6md3C/cyb8RIPb4tTXNF5j0PhS9yOWb7PMPs7VfTDtugs78vkKuWMv9b6Qqw01towMFYJIRbXvyiR1CWqPRY+KfxYbyBTHsVR2zFkegvJhFsWwbOEp/Ke76AADxWQTYPGMaPi6QydGuWWKYsVxRZFGHeHpaZiJHbbUCJ612Z65MfijktV4xN9ioGE2ffSK7rte3q1gEOSTlSBS+vANQHiGWbrq9/QedYNTWhJBzPP+vcUjpN/U8L5RPoL4PLmNkUgcVkjA5z0DrY8qPeX4bpg5oKojtH9WHtHv/Dy79R3AoYZD1j+LNr/Jwatr4yaLHaSLjEgMcle2CKggQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gnsRLvT1WuALmKJeuoBBHZb3siqg0EMnYqQkWLOQUMk=; b=Ks+sUbvhvjChXtHRlikYgppIltw0LOXBBxJWIn963fUYnCJ1J5YHPjODhttS5QgDdpr2t7av+/7K6E6ytqlwnLdzA9Bhs9O1fOEaOTauUgPReHi6Uea+/N5kd9OFJQfY0UpShPhwSmTCc92Zjt6JPY3Q/qG3QkUy7SYQI/GvElx2oUTqmxbcS/Ez0wPhMwTpkzG9VlDF4ZTxOTRjgxvHnUWNxW1kskwAL6CMH2jlzanug5tvTG33vvNiq8eVF/3BvRHqOxSNwzervz9dZ0KLu2uvvvaXdPJb358KbXSQCqodSe50+V1hEtSvDNZwhH14lbI/elIX+OT0WU3t9GDrfg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gnsRLvT1WuALmKJeuoBBHZb3siqg0EMnYqQkWLOQUMk=; b=glRM6pDAn6OsVPsO5+Oe82HHenOG6oK5pH/ahAnPHSNG59UqhQprGRxllo1hjLmN7MaLeM20AZQyheBBb4KZ8b+O+KiVS9ziuIwy8RSWQFT5tLv83DyKdtRnRHx+SCaAhQh3R+9vwtCa9kHSDJw4Lf/YjHFSJ58pV6P53uvOaUE= Received: from SA9PR13CA0053.namprd13.prod.outlook.com (2603:10b6:806:22::28) by PH7PR12MB7454.namprd12.prod.outlook.com (2603:10b6:510:20d::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 18:35:37 +0000 Received: from SN1PEPF000397B4.namprd05.prod.outlook.com (2603:10b6:806:22:cafe::b9) by SA9PR13CA0053.outlook.office365.com (2603:10b6:806:22::28) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.25 via Frontend Transport; Thu, 13 Mar 2025 18:35:37 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B4.mail.protection.outlook.com (10.167.248.58) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:35:36 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:35:34 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 05/10] spi: espi_amd: Add eSPI set IO mode IOCTL command Date: Fri, 14 Mar 2025 00:04:35 +0530 Message-ID: <20250313183440.261872-6-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B4:EE_|PH7PR12MB7454:EE_ X-MS-Office365-Filtering-Correlation-Id: 353e4fcb-db18-46e0-c0a3-08dd625dd90a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|82310400026|376014|36860700013; X-Microsoft-Antispam-Message-Info: v4yN6VB3s+YAj+ytQSyuaOB7DzOO+PAB8LfKcVZW+saUu5mIyjkfKKen1iDGW8BTP0y32wAmU5M6sQ3nhdS4AtZJ7zS+W8Dif4D599BK1DTu1BvNf2IbD+LTVX1Z4bZePsRy0xUuxvNC7GvOYjXq/0jfFgdE85XFwB/7weCmbtwxI5zR7GDo/iacy3K8iBHUkLFTadW6ZMrYbIKNq8v7kLCRdnmMF1zMQHM/GA136UeA/C4iHFmUoHhDyUt9bn17sELiLMtGKah3b0DcS2j2xSRjlzDwG2onPojSkfZnnsZgsVfLAbJACLqaw23vL5VohNuozioU7/EiNQUS517+c2MDStEG14Sy8DBma/ynkCultCgaVzr/pXsMZIxkOzarnRAIKHHW2nWUMZph0FRh6EUo4QJZL+pOz++fwmk+bEXuo6wMjs34ku1r2vaWTMiljbTtjVnl3/omXa+xnOo/8kCW0Yh0XGJRI+IixOUGXdjWZgkqz+PzNLD86QR8kbRnEnlWTcKKxcXOjcmsRL6AMByzfYfMGw5fW3qadf6vUKevXZcAPBn6wWi298pQP7wNQvrXnphvSPkeDwGPvw51tlDklQaPY+rigKifbE7rEapvvamxxWuyjhtoQhn5fZFEykT1CkANboMZhpPxA9iReo8WLi6zxQ3ZTCPLfTzKSarVCBoH0nHulIqML7jgtbqGlmJsnjxrQRM9y6RcW2F3sIj+ZkWNdwsnNhwz43TCBHoy+W0LmfZ9KoqRe+YWrC8+zS1QuqGtOQNotUuJ1yOiEDgULef26O84Rn/jYHU8fyKC8N6PaEEyZ9KkTstNkdFZKr7EtuRtdPrFqL5kcRaewgvz81KSLb5UUAKvJrMJ4+jbp2KW8+4yA5Ya1JS8v7/FighdwPBwLyGZ1g5SILN9ZO3CeezCaOD4U/p3degsqFp1+PR4zeSv/XJp0JyBt7048l46GHT633f60IOIVi6dXzYwYOHI31/ZPLLHNJL7dVd1LwpTeAxM4YXLbV99e0wF8HfUO0xB2tH6yHdiiPttsun2iHQFQNoKRBLadKFCDePtJgEcEHJhuioX7hlrxSJ+sDj4KK0tpGkcF7hrZRzKqN6X9Hm0Jun2Nx2VBskaURW4zH3DrULvx7QMy5YEIex/VYC2UVPol5Br2opfozc7FecOgRMPPsVjekxPaWfIj2LbZz2hXdHP/gSszSIxfe1FSRXLc58gpfr1oOx38C6amsyMkoH0OBIM6NW5uwm6jIqFfL9iFyYjnQhvlLbn8vGbLy9rqIhVJ5d6L2kPxhnJLN6WfEGzOYHJ1JnVVhTH0cfX7BWQFHnPkeFOiCyW53FMmiz57cjGgnpnD/rBT9Miw/y0J4Lo440dSTk60WhRdQnumSbun+z3u/pyDPvxqR5HooHyLeMtsMQPyoSuBGXzOhDhw90U/7WkeDmOKKrUzn55n/fZIF/WkevmhNtO8mz77Re9aBwj0TShiLrVjxd5Rg== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(82310400026)(376014)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:35:36.8694 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 353e4fcb-db18-46e0-c0a3-08dd625dd90a X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B4.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB7454 This patch introduces an IOCTL command to allow users to dynamically configure the supported IO modes such as single, dual and quad modes. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-dev.c | 40 ++++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd.h | 1 + 2 files changed, 41 insertions(+) diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index ba2becdec8e6..821cc0486657 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -166,6 +166,43 @@ static int amd_espi_ioctl_get_conf(struct amd_espi *amd_espi, unsigned long arg) return ret; } +static int amd_espi_ioctl_set_io_mode(struct amd_espi *amd_espi, unsigned long arg) +{ + u32 ctrlr_config, slave_config; + struct config *config; + int ret; + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) + return -ENOMEM; + + if (copy_from_user(config, (void __user *)arg, sizeof(struct config))) { + ret = -EFAULT; + goto set_io_mode_free; + } + + ctrlr_config = readl(ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG); + + ret = amd_espi_get_general_config(amd_espi, &slave_config); + if (ret != CB_SUCCESS) + goto set_io_mode_free; + + ret = amd_espi_set_iomode(amd_espi, &slave_config, &ctrlr_config, config->io_mode); + if (ret != CB_SUCCESS) + goto set_io_mode_free; + + ret = amd_espi_set_config(amd_espi, slave_config, ESPI_SLAVE_GENERAL_CAPS_CFG); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Set IO mode failed\n"); + goto set_io_mode_free; + } + writel(ctrlr_config, (ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG)); + +set_io_mode_free: + kfree(config); + return ret; +} + static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct amd_espi *amd_espi = filp->private_data; @@ -187,6 +224,9 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar if (ret != CB_SUCCESS) dev_err(amd_espi->dev, "In-band reset failed!\n"); break; + case ESPI_SET_IO_MODE: + ret = amd_espi_ioctl_set_io_mode(amd_espi, arg); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index 3c6e9b92c08d..f1185f877a05 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -143,6 +143,7 @@ #define ESPI_SET_CONFIG _IOW(ESPI_MAGIC_NUMBER, 0x1, struct config) #define ESPI_GET_CONFIG _IOR(ESPI_MAGIC_NUMBER, 0x2, struct config) #define ESPI_INBAND_RESET _IO(ESPI_MAGIC_NUMBER, 0x3) +#define ESPI_SET_IO_MODE _IOW(ESPI_MAGIC_NUMBER, 0x4, struct config) /* * enum amd_espi_versions - eSPI controller versions From patchwork Thu Mar 13 18:34:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015780 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2040.outbound.protection.outlook.com [40.107.92.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 78D8F1EFFB8; Thu, 13 Mar 2025 18:35:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.92.40 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890952; cv=fail; b=NrbPXjboI5BpDBLxsLQcIVBG35fGCMKfgG704Rf58DQLHVdt7NftavGu1Sjl2ZcgnMUusynppMw8EwNb7NyaTOoxOUbnV8Cm4S3Io/3C1Umalk2BgRpsKL/IStK0ma4eEyQGtuxl6XH144YsiQjh68MSuao3moX6/gsxJelgsiU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890952; c=relaxed/simple; bh=vrsdyV67dbH7lqDgBT5321evSM9/fW7oy9YKW88k/e0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VX9156ZdYFT9D/R56CDHCZ1NHWJPeZSAftVMwqor3uf71H+UsDuWiDFlSdKCc4gbLEJArAoIfw1QvemTnvDm0gYpCjrxjkyWEuT+0/WyHXad47t92iSVgvCvc81o/sftRCZMjEzlxumgzZ6oz6WHWzB0AjGMRo/r+vmaXhhEXRE= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=dslDcyGz; arc=fail smtp.client-ip=40.107.92.40 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="dslDcyGz" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=UjDY5O95seApcmywBLw7Wq928o/s/RYBcpNqjoSSGNqQzk5XoqeUtCcObeVJNO6rR7kQ9+3vukrebbXC+K4YZzI11pIFd8RLI55cTu/RiofJpfNjrLMXALbJ1tN0LZMlMVxfQC5wzZ6rU+een2m0Vq2bTwDDycbhU5ww967QhG5Dp++O79zPMoGsQQN9F7nfMHvjKEbgkTwQ/QW2OYRIXVLBrxdkaiFFfH2VmpWbIZnmtPSRBn4hsRN5MGjJaez2sUnvj1SzEb+2cCqAw19PNq8pirrepmBID1LlO7vRNjYcYaMRiZxWgvrER75rKBMsNCu+sQZO7LhxKCxZONdu+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=f/Dx/k7A8UTk29uhZRnTdTCbm9/Um+mK0rwmjZQa9t4=; b=f8d83ox52+N4/pNpXj9XSyKm0AYxE5S5nmjnNdd9k4tKuSxbLcqlpGUQfIG4zFVqv6/AlRm5ByQhcyyqP839FKu/JKUXtumhTuSRUuHy7/Jd+D/ap7i7ip8WjU0heb1sQoJBYRlP/eYc1BdzyZJavyXI91azEtsnuSvKzq76Cij7gMvgOFRT1G+r85sNp8p0+BRXsvgAyuGtFxjQY976mDCRG8nkf62FV7E1Dj/geYmKE4ID/2V4rYLJFeK/UqyBMDi6Jlj2XUMBlJaRhcRbn1cw+6My4dhK6X/2B30FlJcJwwsv4gLOfuOBgwSAA0ElilqPnzU1ICWV2OSaNT30AQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=f/Dx/k7A8UTk29uhZRnTdTCbm9/Um+mK0rwmjZQa9t4=; b=dslDcyGzFDJaQR6tniN9D7niZR9n7aBVnYXU9aILm9Pi3fpx616QfL4QOMvlmqy+18TXOvexhhDZVySIPXBsJTzWRF4mjFE92b8mep2cLCOBFuvdbFzJSfyVK/l4qhuHC927GJ4Z/GX6MDUMt3wp+a8ok+mouJ5xdkYRkqMwXJw= Received: from SA9PR11CA0005.namprd11.prod.outlook.com (2603:10b6:806:6e::10) by BL1PR12MB5825.namprd12.prod.outlook.com (2603:10b6:208:394::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8534.28; Thu, 13 Mar 2025 18:35:45 +0000 Received: from SN1PEPF000397B2.namprd05.prod.outlook.com (2603:10b6:806:6e:cafe::30) by SA9PR11CA0005.outlook.office365.com (2603:10b6:806:6e::10) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.25 via Frontend Transport; Thu, 13 Mar 2025 18:35:45 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B2.mail.protection.outlook.com (10.167.248.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:35:45 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:35:43 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 06/10] spi: espi_amd: Add eSPI set channel IOCTL command Date: Fri, 14 Mar 2025 00:04:36 +0530 Message-ID: <20250313183440.261872-7-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B2:EE_|BL1PR12MB5825:EE_ X-MS-Office365-Filtering-Correlation-Id: 18c795d5-cccb-46fc-f0c6-08dd625dde29 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|1800799024|36860700013; X-Microsoft-Antispam-Message-Info: cPis81+b0Xwsg3CKkDQKHB/iJiY2mUW8pV/tTqzi+pHIXGujIdSEDK36SP/SZMUvrHsMNqVQdZg9bj7bChmy+gYH3BBuG8SCPvMxQL14VcD9AAG82xAm3PSVSzzz0xswOZoei6KnS6X4KWZWL63tXg5NI//aiP/IB2rwdgcHeQ8ydy/wZLSgnsUhli2oqDIVkP/h7yQV4/P/n1zz1uHOAp2HA1vcU3ZA7onsqvacl+SKPy9E9Ri6MdSMe7LTlnElT2wU1Jhf/3ZG/cCErIIWCFiuPSjPRrEiU8fu8DjuBGV8tiKzuHyoXi9HpAf7xaOCvCHEioVRgLd624aAxoTFYgrvmWwJBLX/A/9bvzWj0asAhaPRNx6KafWWnKyrlRC9nvsX64jL9j+Dw6prqpc64NepH5WLCdEke5MRfuyJEH976yq2NW3Z75KemkUnREK9/5k/HWgI/pmVMsm+OK+M/wkxbnFtUmbgfOApWRfbeIYaV/wbBXYCbNY1MwSPK7PEhXiripyz7AAi8bP4ZTExzQsqlSyLcuEFO3ry5VHHGCE7CuRPKIDMD3wsd+TAOHQzjv9gZToF+qp+qtFLzHNiwQcxvE49jK4oFXXScDDOMI/jv/hwyYAWTI0d4+F8L2DmjAznmwT7jXe5HVT/ArfbMCz8s8/21ly47YKMu4EsPK46Zr8DSTsahSx26dkriYvuNK/1XCuy/3aaW+S6G7dQktnqAZIJUyQua6DttiwVmfLwQRLphUNpZwKNiQslyePil0GGMS2c6V6oxxMdjDGVL6I9rmJPCay7nlbNmTbZ4tq0dsMfUgcNaSuQXAU/q32VbcEtoI8h+Za/VaBZ9VQ4Zlcx8EEmD+V7AXbCyfNbyOGzp3En/ITqaTsQ2FX1VNJDk35RIxZjKZfepJ7qhjNlWXG4XZ1C+suvRyCnv01iL6VVKV0pJvn/XGLh/IIgZNC9dmZwxLqvGQVS1C9gV816+OJAXd2Jft08e/w0Np9xHIF+aJeVvhEyjm2+1WGxTQrdfmuuShpkaivbXt077MHNHSVhIFox7xXhG2JCCunmzXxDwhRn1zZBUZ5lAJ1pVRzxIfvdpMp/EXVWexGYaPTwS7JKtOZ9AzmB76d8KHLhVyr9rZmAG4/HdIMHGg8bVE8S2UNx25VygylJQh4aTdCQWPNTFiup7LNMXNQ7AJWFz1FwbqO/tZ4ZOIKOoqFG14s6K189vKgePPZPKw8U/rATT59A6RYlZcnkO7558I4k+zjBmP6LOLrgjmwUu8fthQXBcZRLyWgCuk2HNIwdEswJ7Dv62jVBxAVo0uLv2n+dZPZ99pOKqwP0whlby7pTp6OSrH7Bbfgp8QuX56RYOH6MKSnkNkeJ8N7C5AQb7ixFJWS/qQF7zoQjGzwzhXpLB/JNj9RYBm2z59/O7zJdUZTbYKqQ1KQUlYkcoj4xU4oou0DHw6fSbmGiRzwDtmxEyhZK2/8o4FBKiKRCxiKSRI4+ug== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(1800799024)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:35:45.4624 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 18c795d5-cccb-46fc-f0c6-08dd625dde29 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B2.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL1PR12MB5825 This patch introduces support for a new IOCTL command to set the channel of eSPI controller. Currently espi_amd driver supports to enable peripheral and virtual wire channels. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-dev.c | 49 ++++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd.h | 1 + 2 files changed, 50 insertions(+) diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index 821cc0486657..c78a9b2b059b 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -203,6 +203,52 @@ static int amd_espi_ioctl_set_io_mode(struct amd_espi *amd_espi, unsigned long a return ret; } +static int amd_espi_ioctl_set_channel_mode(struct amd_espi *amd_espi, unsigned long arg) +{ + struct config *config; + u32 slave_config; + int ret; + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) + return -ENOMEM; + + if (copy_from_user(config, (void __user *)arg, sizeof(struct config))) { + ret = -EFAULT; + goto set_chan_mode_free; + } + + ret = amd_espi_get_general_config(amd_espi, &slave_config); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Get configuration failed\n"); + goto set_chan_mode_free; + } + + switch (config->channel_mode) { + case CHANNEL_MODE_PC: + ret = amd_espi_setup_periph_channel(amd_espi, slave_config); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Setup peripheral channel failed\n"); + goto set_chan_mode_free; + } + break; + case CHANNEL_MODE_VW: + ret = amd_espi_setup_vw_channel(amd_espi, slave_config); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Setup virtual wire channel failed\n"); + goto set_chan_mode_free; + } + break; + default: + dev_err(amd_espi->dev, "Channel: not supported\n"); + ret = -EOPNOTSUPP; + } + +set_chan_mode_free: + kfree(config); + return ret; +} + static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct amd_espi *amd_espi = filp->private_data; @@ -227,6 +273,9 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar case ESPI_SET_IO_MODE: ret = amd_espi_ioctl_set_io_mode(amd_espi, arg); break; + case ESPI_SET_CHAN_MODE: + ret = amd_espi_ioctl_set_channel_mode(amd_espi, arg); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index f1185f877a05..3774918d994f 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -144,6 +144,7 @@ #define ESPI_GET_CONFIG _IOR(ESPI_MAGIC_NUMBER, 0x2, struct config) #define ESPI_INBAND_RESET _IO(ESPI_MAGIC_NUMBER, 0x3) #define ESPI_SET_IO_MODE _IOW(ESPI_MAGIC_NUMBER, 0x4, struct config) +#define ESPI_SET_CHAN_MODE _IOW(ESPI_MAGIC_NUMBER, 0x5, struct config) /* * enum amd_espi_versions - eSPI controller versions From patchwork Thu Mar 13 18:34:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015781 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2079.outbound.protection.outlook.com [40.107.220.79]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EE6AB1F03E5; Thu, 13 Mar 2025 18:35:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.79 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890961; cv=fail; b=DDRsr8foZ/Qu6zZDIhBRDEtn0Fm7DSxnnzeTpqs311ZlqfmJ7l9OdDxbSljLXTQJA5H2Y56UrDAYAcDTjj+Z5lez8kvQiTknmI1Wk7FC8eHoMGKiKRkUh3A4T8wPM9dGD6EU6h8s68WYqUfruyLXh0s4h+yhykJKaA7IF1s6r8s= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890961; c=relaxed/simple; bh=5b7ZkO9cerk/DdyhUKUfCfM2ryLFah7BrKfxz6ns8I4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nsPbxco0UJRnbS3VZ4WBL8eUFL+DcPgnGjRtiFxjwsNhze30bO/vr7hpS/50SGeuInwUrnuTPMFh6G2dR35c12KjOOuUfNehYV+mWowL4rTrS0IqZuZQkIOlf1yDpsZW0KSWsLXB30tIhyVFN1OwwkV9dniySqJFR4ookNjXzVU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=WAfOIlXF; arc=fail smtp.client-ip=40.107.220.79 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="WAfOIlXF" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=QjRS+O4aFejXc0fQJHndzSnhk5IjKVCGBJsC27re5ETwxJxNojYu2lDMta2i9epeNVHYJHZxtESqmcVMe1Kuwnzxn5PATkX7XyepXCAMWgTUf4uGDMH8LdPRHK3+uAshmTPmjplDE8p/w4lKqeIpFPaWg0fpTOXXLHTTQmpiGsvFhtK0kN2R4bSXg3l8TZLUs+GPjHJVvSPhSL2ODnjq5/EXU8qx5JBEQNiUHGblSo5uG1PuqHsJcAHIFp53TCFCuoqYGBxjg9T7ejLAtiYcOxcHehfSjrLH9jOf/p0th18JHcHv3Clt1cX14kik9LZizgbghglfMEdAS8eBFFwlQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=i4NLPVRNjIqENFlmpIOZI+Xs0LZThu+Do0vfhWWsQms=; b=mGD9GLOZg/q24o+MM6B0MqOWaoK6P8zjLu2tRwqBYJlsAEYsEKPifeiOh8ojVBtGrW+OFvlL3uicT6FmZQPFtxxHSFOyPlmL3W3XnoZDY7fbKrUZee4qRlEhGtm1QHgW/rnxYFVFDbKJpRG3MZot92cPSsDaf4O075TUn3LVmsQPA5hbwsuaqgzhzUvuBaj6q5x0TQRQxDC/atsXKHFRrQterleZ5cG5zI44cKHBJFPz1IpD2D3jPDdWUVYFaKda12EB2XdpOiEMRU3olD3KwFm0Wtw3gUye9WKRkHfjyM2SUjTu9ZhQooRxmClvrpkrRKD0DPi34wSfi/zSdYL0jA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=i4NLPVRNjIqENFlmpIOZI+Xs0LZThu+Do0vfhWWsQms=; b=WAfOIlXFq+nkMe3RlqSurOElx8o5z1CaTa9pDt2GxSTI++Q0Juv5QIESF9E0MsTaqYuf9PWHVbVj07nAHA2br+d/zo9/ZgtSlBEUNLX49nktXNfT64VBKZjoAZvzh9eNRYRjGX3FgW0kSTyv+JmGiodAAOTXIFRAQbqVO9B38aE= Received: from SN7PR04CA0220.namprd04.prod.outlook.com (2603:10b6:806:127::15) by LV8PR12MB9083.namprd12.prod.outlook.com (2603:10b6:408:18c::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 18:35:55 +0000 Received: from SN1PEPF000397B0.namprd05.prod.outlook.com (2603:10b6:806:127:cafe::72) by SN7PR04CA0220.outlook.office365.com (2603:10b6:806:127::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.26 via Frontend Transport; Thu, 13 Mar 2025 18:35:55 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B0.mail.protection.outlook.com (10.167.248.54) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:35:55 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:35:53 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 07/10] spi: espi_amd: Add eSPI set frequency IOCTL command Date: Fri, 14 Mar 2025 00:04:37 +0530 Message-ID: <20250313183440.261872-8-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B0:EE_|LV8PR12MB9083:EE_ X-MS-Office365-Filtering-Correlation-Id: 969d2c78-9bac-4a1c-f15d-08dd625de437 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|36860700013|376014|82310400026; X-Microsoft-Antispam-Message-Info: W89zPNkdHP8Ffau66vW43ifufCEVWRv0LHdLEh5vu6GvCxSX84yhRh3PTFVuJdVS+p0Wde9G/YsUacd/FgZ+ZouDz4BiDASJ/SQaX/URUdWGUFwERZ3XbHKKHpg9uhP6MuoefNkHxmD5SgVfeHHCU29psSyMoESMRdssx/KjBiUQ5J5Dr0Xiq6g/qM3OJyaWQAwAMPSP5elYLOZN5V4UBRzb3XUDvHWDObLyP6BRJ3WE4iLMTUjrlDRmBkvGkonj+Z24JMw+O3h9aB0JhSdb6s10YjoW4BEP0NVhPklhiaqJIh0rhPlssSBQpTFtWq20JXpe+Eg1yP/8Z0F3Kvhlq3M2Fqkg8Qq5Ra9imDqcOZESPr4Cy9IPQsNOEurO7P7kMH0YCpu1YGy+QeZ/Bebcmfi3tYv53dDqxGTRju6LotPmHFJH4YnAmCGc/obAedmchztOvT0Wai+tFunjEerScWmHTheAiK5fB4hzONZWyABEfLQ1PipzzqrPA2j1nfTqkd5GScSkb+y2HejUN1k4Wd/TxwU16lhycDbykkrlx7YJCitChqNAMkDvOpDhH1rPOpYI4ZXY8CdY0DkPV7RWiXUwT4vEh8PQKqMyAaIuwh0vXhdoYx9QN5SIgyS6SUSuUog3wABNa5d/x94ZUVYh6mNZO07wViAt9gJfAe4J7qJgXNxARz4VkFebubtrxNpgiKvazZD6/zNRJFNoo6Rhei3D5hYHJL0qbxavNQJxS04lgNJCKnnsetXv9RBOz95i2YD+527hjtt2BYX6QYfZYcdWIZgiU9ZGTf5hexDz/0K5t32u9xA9SE36TSAqv5qj8JkwH95yhYlRRYhxI/tr7VmncFTVoxnFmChuVDZrpNdzMunBiTGtbogIxopHaCFtxsNa1QYotSWEHj60PdvggjCMWR63w2WJ3Q5TYcOlIRceNT3UFOqUxad1lvFaLQoKhFP4Z/2IrEMBV7vMLBBMYFBc0p3F/aFnia9NkDdLlhv5wzUZhmZ1apNbOXyG6yn7e/pjEuKWRXKM12eSl1VzjK1HZLipgvyeCdOzosS7eK02tM6IyL78phNb7mSdwcA9o28CcmM8p8tLsATTAEd+DzBsWT+w8i34yiXyQLZVtbvqD7xquxpNQaePAwX4Ohhkftg9vcmu8hsasJwTVNeEw0Dpi0Ulpu1pFtZbGD22IpeL6eYuAYnrWycZDNXHhioWVBxxrciGLEETznK6HI0pac63TFBnqCZvrubRVoMABXLKc0URKUGbVs8+q1lAiotMM/+3zejtcRJlGW9bGgkF1/VUchvgt2/MI1PfxCXIGQcTOCyWm1VDuBeFJ2lzXjGJZnOhL+I/JmmbiHBwWLekbMZ+efY2a4BHIbqN0TP6J/z3Lo3MR5gmCBl2iWvBe7+UFfYliD3tYNGbZ9iXhu91V/DJGE1dCJFkzvf9GrlAsOJDOhdfboi+QITCNDSk9c3oRUQsWA6KE7mU3LSjSejYzQ== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(1800799024)(36860700013)(376014)(82310400026);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:35:55.5736 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 969d2c78-9bac-4a1c-f15d-08dd625de437 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B0.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV8PR12MB9083 This patch adds support for a new IOCTL command in the espi_amd driver to set the operating frequency of the eSPI controller. The frequency value can be one of the following supported options: 16MHz, 33MHz or 66MHz. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-dev.c | 40 ++++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd.h | 1 + 2 files changed, 41 insertions(+) diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index c78a9b2b059b..9f1968566980 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -249,6 +249,43 @@ static int amd_espi_ioctl_set_channel_mode(struct amd_espi *amd_espi, unsigned l return ret; } +static int amd_espi_ioctl_set_freq(struct amd_espi *amd_espi, unsigned long arg) +{ + u32 ctrlr_config, slave_config; + struct config *config; + int ret; + + config = kzalloc(sizeof(*config), GFP_KERNEL); + if (!config) + return -ENOMEM; + + if (copy_from_user(config, (void __user *)arg, sizeof(struct config))) { + ret = -EFAULT; + goto set_freq_free; + } + + ctrlr_config = readl(ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG); + + ret = amd_espi_get_general_config(amd_espi, &slave_config); + if (ret != CB_SUCCESS) + goto set_freq_free; + + ret = amd_espi_set_freqmode(amd_espi, &slave_config, &ctrlr_config, config->op_freq); + if (ret != CB_SUCCESS) + goto set_freq_free; + + ret = amd_espi_set_config(amd_espi, slave_config, ESPI_SLAVE_GENERAL_CAPS_CFG); + if (ret != CB_SUCCESS) { + dev_err(amd_espi->dev, "Set operating frequency failed\n"); + goto set_freq_free; + } + writel(ctrlr_config, (ESPI_BASE + AMD_ESPI_SLAVE0_CONFIG_REG)); + +set_freq_free: + kfree(config); + return ret; +} + static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct amd_espi *amd_espi = filp->private_data; @@ -276,6 +313,9 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar case ESPI_SET_CHAN_MODE: ret = amd_espi_ioctl_set_channel_mode(amd_espi, arg); break; + case ESPI_SET_FREQ: + ret = amd_espi_ioctl_set_freq(amd_espi, arg); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index 3774918d994f..e5760db7c1d3 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -145,6 +145,7 @@ #define ESPI_INBAND_RESET _IO(ESPI_MAGIC_NUMBER, 0x3) #define ESPI_SET_IO_MODE _IOW(ESPI_MAGIC_NUMBER, 0x4, struct config) #define ESPI_SET_CHAN_MODE _IOW(ESPI_MAGIC_NUMBER, 0x5, struct config) +#define ESPI_SET_FREQ _IOW(ESPI_MAGIC_NUMBER, 0x6, struct config) /* * enum amd_espi_versions - eSPI controller versions From patchwork Thu Mar 13 18:34:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015782 Received: from NAM04-MW2-obe.outbound.protection.outlook.com (mail-mw2nam04on2054.outbound.protection.outlook.com [40.107.101.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21EAF1F0990; Thu, 13 Mar 2025 18:36:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.101.54 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890975; cv=fail; b=QfYtt+8m5S/lNWK6mXrxs785frOQpRm94HMPPFs1U0+si/UMfPXZLxONrhB8QUf4NOupQDGAt+6Z0PbJinzVde7iouXLg0L/8dGBptpjtlqg5K98HY+3Yu0PiRr2VbwEOPRUc+MzoOsgEmcV6M2xU/MO/ieQr/NOhWDsIC0iK2o= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890975; c=relaxed/simple; bh=MOhIAO/MgceUyoSy8atn8t6SZiRGoT1FBPrHnv7DTlQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=h+J5pALpH0nZAzI9MqsQTbaJ6ZNVxwxzoAas2REgxS1P2Hoj6rkXnpzP8zMoAmPLogHM7hbQqMMo0xl72ZkI+OOPC8x3ITZK8FHGE4cgnKo5Df4ydP2kmgFTu+ffJcX2bdYbit/zh7SWDsyulKKAKHgDlzARG0twKEe/fpsHCDM= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=A+pHRf3k; arc=fail smtp.client-ip=40.107.101.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="A+pHRf3k" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=SGDuIbsexwx99PsHIRgp+3RCvNW8E3e3tZjJN224VKD3oPSwCkiL5rCn9GEvz4GEKzsxdWBZy/F2GGuWonTnV8++NUHuNt9XsUGC4kLKjCWkb8EScFz/KoeCRV/5Cac40R1QTzvczx2PnZr/Wh4PvTDmCw0LLSEHojstpa1WgrPjQ5uObfdpiAD0HO3L4/06tgID4lDA6Q+lA28qn5Q2UvSjU6Q4CXWjfOIzh3fug3EqvZQ+Zv9sV3PRNLJQpNQ4kKJe6qIhPviLf8wz60w/axRP5z1PnK7PwvEFAjYn+lg/QmV+X5hHa3j/NU95f10cNgYB9eCWEq8mcCojl0OQKQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gTTmlTjDWm1tLxRuVsp9NkQjtIrcTAvS1pqvB8RuzbE=; b=uOV0nfqB76Sk6YovM/hIJq86zwqFNh6UsWkLkRmHTVEDkwoB+fH9LYVqwGEWp7bjqz8wce7CH+5Rygjs5xc1DlxJVq1vZJUUPY2DUO+AFPEXSkI6uVrW4BdoXSKL2Yy/ya3u9T1PNdATC1luheBUuCihz6NIPIuvGIhiUIKa8V5nRLuXWaRaWrpchwhfJ0/VYk/omdsCJisoDMxp+5Q0kv6jByKLyAoAEJqevJsMA9NsR79sR31J8AvUh5UIQn7Be+5bK6Oy610O7iHkQt1nkJwmnxVJ1fScWLdI0GKPEDNP5+p2DQUq1/sskYbIM8EQprfj1UD9jObbZEuO5D/fAA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gTTmlTjDWm1tLxRuVsp9NkQjtIrcTAvS1pqvB8RuzbE=; b=A+pHRf3kUpIiCcABnHRuz64CzUrRfcqxeQt2Tqf8gzNzkKodFlLDDYWDXx2A8YkTE90fZ8u5DQaJS083PKxAQxQ09rWEFbZFUZZBQBjeBM3BdMsHKJzPjd3j+vL+0YLGGcYiKVw+KIDeJcNavgPY7z54MK+la6+tyIjtwQlJbBg= Received: from SA9PR11CA0003.namprd11.prod.outlook.com (2603:10b6:806:6e::8) by SN7PR12MB7024.namprd12.prod.outlook.com (2603:10b6:806:26e::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 18:36:07 +0000 Received: from SN1PEPF000397B2.namprd05.prod.outlook.com (2603:10b6:806:6e:cafe::8e) by SA9PR11CA0003.outlook.office365.com (2603:10b6:806:6e::8) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.25 via Frontend Transport; Thu, 13 Mar 2025 18:36:07 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B2.mail.protection.outlook.com (10.167.248.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:36:07 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:36:04 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 08/10] spi: espi_amd: Add support for IO/MMIO configuration Date: Fri, 14 Mar 2025 00:04:38 +0530 Message-ID: <20250313183440.261872-9-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B2:EE_|SN7PR12MB7024:EE_ X-MS-Office365-Filtering-Correlation-Id: 7a74e4b3-bb2f-45ef-3141-08dd625deb36 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|1800799024|376014|36860700013; X-Microsoft-Antispam-Message-Info: 9va9e+oZULPHUHXrzS9t8A0SEnq7i/dke8etNDwzgNOl8/Uhsy4TnxIyCHwT5YM3itTrAN7pQNPSxvMXExoAd3tX+nkrqK1qxkh5F1Ln2tt0uwbYw9vWAqALOxMZx/H9TFZIvN7dvi+kxrr58ugPVpHifDqGFw/gZRDY41OXZ2C9j7EroYeEaf+hnr5MT6cG0DPh99qxitXhVgu93Opda97chTCOWRDYkkjBNQ+3c1GI1T/a40l8iQTNPfEUSqz6U+/7ocGv7UtCyvucFW9hl0JVJmAgUe8Agvrdu9PsU6MVELm38KpWjtlmX+nO8334HzZ2eXbL2Jb+LWzB3CbrWHw/Mtuux6vLm7t51wxSMWvC+E+VfRZ1WeuSqZMVxiF2FvN7KKM7zwXnYVP74uBdokrAYZ04gYgvevrCeD90OofdEaPkhcdSa4LO7sAMlbUES64SlSWByMaFH3hVGg0X31tf4IqD3XpKshsRKt3eH3HzWptXDh63/4Gpqeonz2XyFSDOmpeFFxL6oEOrtodlQWMV7s1oi4l45q9OmFIMZ4hbUBDpV85sfOw/baNRRONIj6I9y7CYnxx3A35TDhszQ0AE+tUYJO8yxM2xdBGgR2FfWbUim+8UVNH3de9S/jOKVzSrGo9xICAX1pFbucRmWWmpt7rqosvo3sHUHSOKli9FlwcLcwFtsA99vIj0gLEJk/58hnGInOgHMGRX+AmnUGWKPUgg0+hUQrpFX4ZiTHcBeSe5it7weQwHeBz9muvmhdyBB6p8PD8ki6jMbFgTOd28e2gKiZc2Www4a48iLx/FCxfstHARA+iaQ29Rbq0NyO6i3hdEO2o34Iqz49O39k9/mI5vpAXsi9IwT0DBV2EF8tD2SvSdfsMu1deX3razhQAe73qd3QS90tEN1WZZ3a7RkonHaD1y1WbzUFFuVuidsjeEWl5NqfWT0gvx3/AygmywkT2Tw72m32dKpyPKv/dkJXHEmdw8WKhZyBRaM0jTSmP7CktbXYhGHG0UE3UhmAcjI2eE/7KoRouNWFFb/mO8n6t6Y8Y/PL58UG+jjMuJgxpgxHNm5K4dIe3yvjiNt+3H3riUbsS9phELEiz4rWzz4JXkBl69GT0LUZcfpa03/uYRGgWOMY1MWvPvtu1c11A5Fk9+uVBAsnoybw8vY9O2ZbtSfBO4I0h+jrb3EVuM47dni7jSBqadddKC2UVVdeJh5c1qgtkjWhIuDzg6ntkTVEdhcx0YNKL1yJogk6R7wid0ptcRh5NdZjO5ZFUp309Q/fYsKAQlORjdS2oodbGRtJAPMo7iwoFuD9aB8sMBEYPiG3BvOF4fp4H9sv1kKSliNLcyPI9B4gmIExjC3Y0ZcawwE3SX6NOadMUztrnNavTdMr/wad17scdchTo7TH35Gamdro6O61iWNhWU9j1Syk1CVKttRxyY2e49FLmiwJIPDHHwCSBD6HdpkXSvAGgTZgIZif3sdGW7Gz/E4w== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(1800799024)(376014)(36860700013);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:36:07.3531 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7a74e4b3-bb2f-45ef-3141-08dd625deb36 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B2.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB7024 Add support to configure the eSPI slave0 IO/MMIO address before initiating the peripheral channel IO/MMIO read and write operations. This patch introduces new IOCTLs to enable, disable and read IO/MMIO configurations. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-core.c | 157 ++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd-dev.c | 53 ++++++++++++ drivers/spi/espi-amd.h | 91 +++++++++++++++++++++ 3 files changed, 301 insertions(+) diff --git a/drivers/spi/espi-amd-core.c b/drivers/spi/espi-amd-core.c index 72a625b8b16d..3704cbd816ae 100644 --- a/drivers/spi/espi-amd-core.c +++ b/drivers/spi/espi-amd-core.c @@ -553,6 +553,163 @@ int amd_espi_setup_vw_channel(struct amd_espi *amd_espi, u32 slave_caps) CHANNEL_MODE_VW); } +void amd_espi_get_io_mmio_decode_info(struct amd_espi *amd_espi, + struct io_mmio_decode_config *config) +{ + config->io_mmio_dc_enable = readl(ESPI_BASE + AMD_ESPI_SLAVE0_DECODE_EN_REG); + config->range0.val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_IO_BASE_REG0_REG); + config->range1.val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_IO_BASE_REG1_REG); + config->range2.val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_IO_SIZE_REG); + config->mmio_target_range0 = readl(ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_BASE_REG0); + config->mmio_target_range1 = readl(ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_BASE_REG1); + config->mmio_target_range2 = readl(ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_BASE_REG2); + config->mmio_target_range3 = readl(ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_BASE_REG3); + config->mmio_range4.val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_SIZE_REG0); + config->mmio_range5.val = readl(ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_SIZE_REG1); +} + +void amd_espi_set_io_mmio_decode_config(struct amd_espi *amd_espi, + struct io_mmio_decode_config *config) +{ + struct io_mmio_decode_config io_dc_conf; + + amd_espi_get_io_mmio_decode_info(amd_espi, &io_dc_conf); + writel(((~(config->io_mmio_dc_enable) & io_dc_conf.io_mmio_dc_enable) | + config->io_mmio_dc_enable), (ESPI_BASE + AMD_ESPI_SLAVE0_DECODE_EN_REG)); + + /* IO RANGE-0 configuration */ + if (config->io_mmio_dc_enable & IO_DECODE_RANGE0) { + if (config->range0.base_addr_range0 != io_dc_conf.range0.base_addr_range0) { + writel(((io_dc_conf.range0.val & CNTRL_IO_DECODE_ADDR_MASK(0)) | + config->range0.val), + (ESPI_BASE + AMD_ESPI_SLAVE0_IO_BASE_REG0_REG)); + writel(((io_dc_conf.range2.val & CNTRL_IO_DECODE_SIZE_MASK(0)) | + config->range2.val), (ESPI_BASE + AMD_ESPI_SLAVE0_IO_SIZE_REG)); + } + } + + /* IO RANGE-1 configuration */ + if (config->io_mmio_dc_enable & IO_DECODE_RANGE1) { + if (config->range0.base_addr_range1 != io_dc_conf.range0.base_addr_range1) { + writel(((io_dc_conf.range0.val & CNTRL_IO_DECODE_ADDR_MASK(16)) | + config->range0.val), + (ESPI_BASE + AMD_ESPI_SLAVE0_IO_BASE_REG0_REG)); + writel(((io_dc_conf.range2.val & CNTRL_IO_DECODE_SIZE_MASK(8)) | + config->range2.val), (ESPI_BASE + AMD_ESPI_SLAVE0_IO_SIZE_REG)); + } + } + + /* IO RANGE-2 configuration */ + if (config->io_mmio_dc_enable & IO_DECODE_RANGE2) { + if (config->range1.base_addr_range2 != io_dc_conf.range1.base_addr_range2) { + writel(((io_dc_conf.range1.val & CNTRL_IO_DECODE_ADDR_MASK(0)) | + config->range1.val), + (ESPI_BASE + AMD_ESPI_SLAVE0_IO_BASE_REG1_REG)); + writel(((io_dc_conf.range2.val & CNTRL_IO_DECODE_SIZE_MASK(16)) | + config->range2.val), (ESPI_BASE + AMD_ESPI_SLAVE0_IO_SIZE_REG)); + } + } + + /* IO RANGE-3 configuration */ + if (config->io_mmio_dc_enable & IO_DECODE_RANGE3) { + if (config->range1.base_addr_range3 != io_dc_conf.range1.base_addr_range3) { + writel(((io_dc_conf.range1.val & CNTRL_IO_DECODE_ADDR_MASK(16)) | + config->range1.val), + (ESPI_BASE + AMD_ESPI_SLAVE0_IO_BASE_REG1_REG)); + writel(((io_dc_conf.range2.val & CNTRL_IO_DECODE_SIZE_MASK(24)) | + config->range2.val), (ESPI_BASE + AMD_ESPI_SLAVE0_IO_SIZE_REG)); + } + } + + /* MMIO RANGE-0 configure */ + if (config->io_mmio_dc_enable & MMIO_DECODE_RANGE0) { + if (config->mmio_target_range0 != io_dc_conf.mmio_target_range0) { + writel(config->mmio_target_range0, + (ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_BASE_REG0)); + writel(((io_dc_conf.mmio_range4.val & CNTRL_MMIO_DECODE_SIZE_MASK(0)) | + config->mmio_range4.val), + (ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_SIZE_REG0)); + } + } + + /* MMIO RANGE-1 configure */ + if (config->io_mmio_dc_enable & MMIO_DECODE_RANGE1) { + if (config->mmio_target_range1 != io_dc_conf.mmio_target_range1) { + writel(config->mmio_target_range1, + (ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_BASE_REG1)); + writel(((io_dc_conf.mmio_range4.val & CNTRL_MMIO_DECODE_SIZE_MASK(16)) | + config->mmio_range4.val), + (ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_SIZE_REG0)); + } + } + + /* MMIO RANGE-2 configure */ + if (config->io_mmio_dc_enable & MMIO_DECODE_RANGE2) { + if (config->mmio_target_range2 != io_dc_conf.mmio_target_range2) { + writel(config->mmio_target_range2, + (ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_BASE_REG2)); + writel(((io_dc_conf.mmio_range5.val & CNTRL_MMIO_DECODE_SIZE_MASK(0)) | + config->mmio_range5.val), + (ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_SIZE_REG1)); + } + } + + /* MMIO RANGE-3 configure */ + if (config->io_mmio_dc_enable & MMIO_DECODE_RANGE3) { + if (config->mmio_target_range3 != io_dc_conf.mmio_target_range3) { + writel(config->mmio_target_range3, + (ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_BASE_REG3)); + writel(((io_dc_conf.mmio_range5.val & CNTRL_MMIO_DECODE_SIZE_MASK(16)) | + config->mmio_range5.val), + (ESPI_BASE + AMD_ESPI_SLAVE0_MMIO_SIZE_REG1)); + } + } +} + +void amd_espi_disable_io_decode_range(struct amd_espi *amd_espi, u32 io_range) +{ + u32 io_mmio_dc_enable = readl(ESPI_BASE + AMD_ESPI_SLAVE0_DECODE_EN_REG); + + switch (io_range) { + case 1: + if (io_mmio_dc_enable & IO_DECODE_RANGE0) + io_mmio_dc_enable = io_mmio_dc_enable ^ IO_DECODE_RANGE0; + break; + case 2: + if (io_mmio_dc_enable & IO_DECODE_RANGE1) + io_mmio_dc_enable = io_mmio_dc_enable ^ IO_DECODE_RANGE1; + break; + case 3: + if (io_mmio_dc_enable & IO_DECODE_RANGE2) + io_mmio_dc_enable = io_mmio_dc_enable ^ IO_DECODE_RANGE2; + break; + case 4: + if (io_mmio_dc_enable & IO_DECODE_RANGE3) + io_mmio_dc_enable = io_mmio_dc_enable ^ IO_DECODE_RANGE3; + break; + case 5: + if (io_mmio_dc_enable & MMIO_DECODE_RANGE0) + io_mmio_dc_enable = io_mmio_dc_enable ^ MMIO_DECODE_RANGE0; + break; + case 6: + if (io_mmio_dc_enable & MMIO_DECODE_RANGE1) + io_mmio_dc_enable = io_mmio_dc_enable ^ MMIO_DECODE_RANGE1; + break; + case 7: + if (io_mmio_dc_enable & MMIO_DECODE_RANGE2) + io_mmio_dc_enable = io_mmio_dc_enable ^ MMIO_DECODE_RANGE2; + break; + case 8: + if (io_mmio_dc_enable & MMIO_DECODE_RANGE3) + io_mmio_dc_enable = io_mmio_dc_enable ^ MMIO_DECODE_RANGE3; + break; + default: + break; + } + + writel(io_mmio_dc_enable, (ESPI_BASE + AMD_ESPI_SLAVE0_DECODE_EN_REG)); +} + static int amd_espi_get_master_cap(struct amd_espi *amd_espi, struct espi_master *master) { u32 master_cap_reg, info; diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index 9f1968566980..31fb06f4a3ff 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -286,9 +286,49 @@ static int amd_espi_ioctl_set_freq(struct amd_espi *amd_espi, unsigned long arg) return ret; } +static int amd_espi_ioctl_get_io_decode_conf(struct amd_espi *amd_espi, unsigned long arg) +{ + struct io_mmio_decode_config *io_dc_config; + int ret = 0; + + io_dc_config = kzalloc(sizeof(*io_dc_config), GFP_KERNEL); + if (!io_dc_config) + return -ENOMEM; + + amd_espi_get_io_mmio_decode_info(amd_espi, io_dc_config); + + if (copy_to_user((void __user *)arg, io_dc_config, sizeof(struct io_mmio_decode_config))) + ret = -EFAULT; + + kfree(io_dc_config); + return ret; +} + +static int amd_espi_ioctl_enable_io_decode_conf(struct amd_espi *amd_espi, unsigned long arg) +{ + struct io_mmio_decode_config *io_dc_config; + int ret = 0; + + io_dc_config = kzalloc(sizeof(*io_dc_config), GFP_KERNEL); + if (!io_dc_config) + return -ENOMEM; + + if (copy_from_user(io_dc_config, (void __user *)arg, + sizeof(struct io_mmio_decode_config))) { + ret = -EFAULT; + goto decode_config_free; + } + amd_espi_set_io_mmio_decode_config(amd_espi, io_dc_config); + +decode_config_free: + kfree(io_dc_config); + return ret; +} + static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct amd_espi *amd_espi = filp->private_data; + u32 io_range = 0; int ret = 0; /* Check type and command number */ @@ -316,6 +356,19 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar case ESPI_SET_FREQ: ret = amd_espi_ioctl_set_freq(amd_espi, arg); break; + case ESPI_GET_IODECODE_CONFIG: + ret = amd_espi_ioctl_get_io_decode_conf(amd_espi, arg); + break; + case ESPI_EN_IODECODE_CONFIG: + ret = amd_espi_ioctl_enable_io_decode_conf(amd_espi, arg); + break; + case ESPI_DS_IODECODE_CONFIG: + if (copy_from_user(&io_range, (void __user *)arg, sizeof(unsigned int))) { + ret = -EFAULT; + break; + } + amd_espi_disable_io_decode_range(amd_espi, io_range); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index e5760db7c1d3..ae76243786f0 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -33,6 +33,19 @@ #define AMD_ESPI_MISC_CNTRL_REG0 0x38 #define AMD_ESPI_MISC_CNTRL_REG1 0x3c +/* Slave-0 registers IO and MMIO config registers */ +#define AMD_ESPI_SLAVE0_DECODE_EN_REG 0x40 +#define AMD_ESPI_SLAVE0_IO_BASE_REG0_REG 0x44 +#define AMD_ESPI_SLAVE0_IO_BASE_REG1_REG 0x48 +#define AMD_ESPI_SLAVE0_IO_SIZE_REG 0x4C +#define AMD_ESPI_SLAVE0_MMIO_BASE_REG0 0x50 +#define AMD_ESPI_SLAVE0_MMIO_BASE_REG1 0x54 +#define AMD_ESPI_SLAVE0_MMIO_BASE_REG2 0x58 +#define AMD_ESPI_SLAVE0_MMIO_BASE_REG3 0x5C +#define AMD_ESPI_SLAVE0_MMIO_SIZE_REG0 0x60 +#define AMD_ESPI_SLAVE0_MMIO_SIZE_REG1 0x64 +#define AMD_ESPI_MMIO_ADDR_LEN 4 + /* Slave-0 configuration and interrupt registers */ #define AMD_ESPI_SLAVE0_CONFIG_REG 0x68 #define AMD_ESPI_SLAVE0_INT_EN_REG 0x6C @@ -136,6 +149,20 @@ #define ESPI_CNTRL_SET_OP_FREQ(conf, freq) (((conf) & ESPI_CNTRL_OP_MODE_MASK) |\ ((freq) << ESPI_CNTRL_SLAVE0_FREQ_SHIFT)) +/* Slave-0 IO and MMIO decode enable configurations */ +#define IO_DECODE_RANGE0 BIT(8) +#define IO_DECODE_RANGE1 BIT(9) +#define IO_DECODE_RANGE2 BIT(10) +#define IO_DECODE_RANGE3 BIT(11) +#define MMIO_DECODE_RANGE0 BIT(12) +#define MMIO_DECODE_RANGE1 BIT(13) +#define MMIO_DECODE_RANGE2 BIT(14) +#define MMIO_DECODE_RANGE3 BIT(15) + +#define CNTRL_IO_DECODE_ADDR_MASK(val) (~(GENMASK(15, 0) << (val))) +#define CNTRL_IO_DECODE_SIZE_MASK(val) (~(GENMASK(3, 0) << (val))) +#define CNTRL_MMIO_DECODE_SIZE_MASK(val) (~(GENMASK(15, 0) << (val))) + #define ESPI_BASE ((u8 __iomem *)amd_espi->io_remap_addr) /* IOCTL calls */ @@ -146,6 +173,9 @@ #define ESPI_SET_IO_MODE _IOW(ESPI_MAGIC_NUMBER, 0x4, struct config) #define ESPI_SET_CHAN_MODE _IOW(ESPI_MAGIC_NUMBER, 0x5, struct config) #define ESPI_SET_FREQ _IOW(ESPI_MAGIC_NUMBER, 0x6, struct config) +#define ESPI_GET_IODECODE_CONFIG _IOWR(ESPI_MAGIC_NUMBER, 0x7, struct io_mmio_decode_config) +#define ESPI_EN_IODECODE_CONFIG _IOWR(ESPI_MAGIC_NUMBER, 0x8, struct io_mmio_decode_config) +#define ESPI_DS_IODECODE_CONFIG _IOWR(ESPI_MAGIC_NUMBER, 0x9, u32) /* * enum amd_espi_versions - eSPI controller versions @@ -282,6 +312,62 @@ struct espi_txcmd { u32 expected_status_codes; }; +/* IO/MMIO decode configuartions */ +union io_target_range0 { + u32 val; + struct { + u16 base_addr_range0; + u16 base_addr_range1; + }; +}; + +union io_target_range1 { + u32 val; + struct { + u16 base_addr_range2; + u16 base_addr_range3; + }; +}; + +union io_target_range2 { + u32 val; + struct { + u32 io_range0_size:8; + u32 io_range1_size:8; + u32 io_range2_size:8; + u32 io_range3_size:8; + }; +}; + +union mmio_target_range4 { + u32 val; + struct { + u32 mmio_range0_size : 16; + u32 mmio_range1_size : 16; + }; +}; + +union mmio_target_range5 { + u32 val; + struct { + u32 mmio_range2_size : 16; + u32 mmio_range3_size : 16; + }; +}; + +struct io_mmio_decode_config { + u32 io_mmio_dc_enable; + union io_target_range0 range0; + union io_target_range1 range1; + union io_target_range2 range2; + u32 mmio_target_range0; + u32 mmio_target_range1; + u32 mmio_target_range2; + u32 mmio_target_range3; + union mmio_target_range4 mmio_range4; + union mmio_target_range5 mmio_range5; +}; + /* Function prototypes */ int amd_espi_device_create(struct amd_espi *amd_espi, struct device *dev); void amd_espi_device_remove(struct amd_espi *amd_espi); @@ -297,4 +383,9 @@ int amd_espi_get_channel_config(struct amd_espi *amd_espi); int amd_espi_setup_periph_channel(struct amd_espi *amd_espi, u32 slave_caps); int amd_espi_setup_vw_channel(struct amd_espi *amd_espi, u32 slave_caps); void amd_espi_clr_all_intr(struct amd_espi *amd_espi); +void amd_espi_get_io_mmio_decode_info(struct amd_espi *amd_espi, + struct io_mmio_decode_config *config); +void amd_espi_set_io_mmio_decode_config(struct amd_espi *amd_espi, + struct io_mmio_decode_config *config); +void amd_espi_disable_io_decode_range(struct amd_espi *amd_espi, u32 io_range); #endif From patchwork Thu Mar 13 18:34:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015783 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (mail-dm6nam12on2059.outbound.protection.outlook.com [40.107.243.59]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 991AA1F3BA7; Thu, 13 Mar 2025 18:36:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.243.59 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890983; cv=fail; b=be12YA0KkvxxoueSeW42ZbtAJovZjkuEtDBe8CWUIKzI+79duZjRG60j+/BNkIsMdPWQsSIQJNXjJlnK7D0Q8NgP945T1VfitDIruCI28Fj0cwBZCDov5IYxjwJ/qkBjc2Ox6TUZDE+jc431nCro8R2w5CzB8gmqmKPabo7zNjs= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890983; c=relaxed/simple; bh=MoP1+I/gRjbKp/NJORLMJFt3237v1OA8EcpL/JgstRU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KhqzZjLLluDwGIE3ZFRqXpsFtLm3rc9M8VH25S+pE4jNKQRSMncruRSlb8Ks9of5MHn+of8QvvvApCW76raXGu1YhC4eeq28Ckmyo5fVZ/AY0RzAS5eDYZvUjopWUDlRpUgZEfVXlJqVDu5H2yackP1xMi1J7ZWbirEQunlbiPU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=Ziny6r5v; arc=fail smtp.client-ip=40.107.243.59 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="Ziny6r5v" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=MLe1uBq9OcOZTt3VazANZiAC0g0o5zxAHLiGTH9o8Q6JQrrUgy/feHzf1lV2v7gjeYx0a0F6SgQ1Yq3BdAWC2kfi3r2Poj4IlPRPXZTIFSrQchezZfDyi/pjo69g0FcYvb7vPUHpmlUtJxzib/osyFT3etwgEeaSlVkaYaRtr/qw/G362s8kXrLGHYnX7xypuDzUhR7Tl2J9GsRw4RHxoFa3TS1U5o5SiDsQb3SHC+Sq/ZxKMTKodSdc9Hr5kQckRLLFm3uvu+jjk5+hFd0/3KD4AFT8v5HeKq08RkkeFdTkDFuzMWRfMnW8vIIAWiBVxnpN0SolykdZShWoFzuT0Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=o3o/tevFk48fWdeHWjscsEpgKBHgGgy23zvzRLt2Jrw=; b=OOJO3krsw9hUjf1QWXH8jeUmXG/qOAFJLZrOtxD/tSWdVZYOMV87fh+11cqvL8Fil040woDrCK3yXCk/nJxcGiy4581gHHlXAvdvZ7iV3yq8R034n0seOn//78SiAyM+Vy+WA27ZcHIeaNvsFXWzKgK2kTO+N5DX8b7JydWLOHwvnJbn3EOzRYdfZICRlwfxXF3H5W4+uLZBYi1tjYoznV4l9WGyxdJoIh/N79Mpo/91SI851UHGrKo2fJWNPrpvV3smMBL76dxYma0wc68Eo0Z2PqWl5QDPXKajEiWtrCI2lABmaEk0WsqfFPE7P9ErP1vcgwECq4KaJHP5+OCtPw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=o3o/tevFk48fWdeHWjscsEpgKBHgGgy23zvzRLt2Jrw=; b=Ziny6r5v6iyQDbtGP+cpT2xP6SGIwLMhDs8e8ttDq2eLdxrcrdsPTsevUt5ASRgO2mjrWnIBvVRq8zdQVDop+G98iA3BQ7q0KCTquJlmngmS/vr6JsJCkX+LSelq0ITtrsWmHpu2xUMYFBWPu958wYnEOe/fIPHiH5U33f3fIfg= Received: from SA9PR11CA0026.namprd11.prod.outlook.com (2603:10b6:806:6e::31) by PH8PR12MB7184.namprd12.prod.outlook.com (2603:10b6:510:227::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 18:36:16 +0000 Received: from SN1PEPF000397B2.namprd05.prod.outlook.com (2603:10b6:806:6e:cafe::f) by SA9PR11CA0026.outlook.office365.com (2603:10b6:806:6e::31) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.26 via Frontend Transport; Thu, 13 Mar 2025 18:36:15 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B2.mail.protection.outlook.com (10.167.248.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:36:14 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:36:12 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 09/10] spi: espi_amd: Add eSPI PC channel IO read/write IOCTL commands Date: Fri, 14 Mar 2025 00:04:39 +0530 Message-ID: <20250313183440.261872-10-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B2:EE_|PH8PR12MB7184:EE_ X-MS-Office365-Filtering-Correlation-Id: 7e90072d-b62d-4aab-e8ca-08dd625defbc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|1800799024|376014; X-Microsoft-Antispam-Message-Info: MG8ERoEPC9tFX5KBg2REyoOv7EU7/cLYO8VCdPj3SNx8rVpmVY8SQuHhebZz+RBVfHnb4kyWwKqfixYtjtkQUfdypTi0hJqcEsZoqzuNlstacmam8MP1+3iDmKV9CRt9E++SS+TKGN7a73tJKUSirVxNALRxyyKLjGI1B4xofmNKoo3gy4nJ9PHBt0M7S5kgbp17csabO+b+BmHr1bj0Hq970Pgk3TOf3isn4caXJpUIJoc3a0ik8EPbch1y8iS0UJYDSU63+49VR+TSOua1w1Z/Ojmm78Poa1ygQM7RYUByMz+/mMztJCiU2sMrWQS4qNNYPYrno7YgWlX9tFnCZnJpNC+24099xx8zbQYwdHWJXJw5F7kV1k+Oz9tlO3+zP3BkpEv06iPsaRk4WcrPkvLGx6JRXigWFjSYpBrKLHL6tOfa3p7mslye2Eq7ztQr5QpAAYFe6bEuhC9Qn4brHjP2Oc+w9w+/oDSKonaIA8L/rIQDxVjomoCSg3SUSx0zAWiPL83h/X8vPWAXa/HuT1thdhpudBetXXGS6Q1P5z9MQNuGoKUZbID4c5mXOek3I42IuKK/maHz0gkdSvKrJbiQY3gjLK7HUtcxIGAWgmdtXVLoKso6uFjX/PT9wXrfgH6oYmnYTmCXm6wpSNPbQ2hdiQxNa1H+zXfAgG61n3CZBCn/NnMIfGPEQBGBbtueroAAN6bTkfdYwDGjQAL9k8X60dBGlKSZTXSVzlF3BLLkvCDUv1B2W0StFb1rcPdT0148AJoEz77fT/g4tsoPcPgR72i749cgSp1BbFG7wGEfEm2EQQ/F7KQ+A/1OagLaRLvUM6GFHDRFCEUcSAODQCcKeMFF96GX7HG9rOboKCMNxmNChIMs8dxoBdHA+xtAp9aSCM3ga1KTnfB8QzLY0jbmxLxNpW/01JGQjywFNok5pav9qjKk9xtgPJSYD1FckBs4p09BPgjRqoYFUDeHoTKyxTdZ/iWRv/43iJmbBDKlmnUZH6mGFlfMr3uzISHuPjCH21zmFzjiL0h+KjckFDJoz/90Jd68u+UmcvzcOqbZ3kaam6yk4Ck6NCn9IBk4wzPQ5Ca5Gw1dCAUC+sBUfU/6i2SCPYoKUbUlqdqEUj2iClIZ5TRh1aVWn4EpKWW4pVN44Cxg+bsvGLh1LeN2IdTbcM3uFqfDHIXgsXobsQlG8AWtmCRlfZfkwSbB4seBJTYp9C1rUZy4ywSigjjzfx67leuubepHQeiNHRyt5dIQme7EdYBV9h1Qah6mEB35y1gQwrubb9SDLso3MvL4fIHNQW7zvG/Vy+3cj/7rbw+scexghI6Cu/Qmy9EIf8kTYu/ohnR8YkmN8Qh6PWdpOkr5vYMHiD7kORLRIzAUUmixFa/wvjA5HL87Oij2kalluidlK7bDkY/Y5f9OqPjIxVIG2SWn4CSdSY7FX2FAdQ5G7hsos5fSyeDXLXg181zdHYUY8gCb3rqB0wIHsZpemQ== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:36:14.9469 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7e90072d-b62d-4aab-e8ca-08dd625defbc X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B2.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH8PR12MB7184 Add new IOCTL commands to perform eSPI peripheral channel(PC) IO read/write operations with peripherals connected to eSPI slave0. The changes include validation of IO configuration before initiating the read/write operations. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-core.c | 95 +++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd-dev.c | 53 +++++++++++++++++++++ drivers/spi/espi-amd.h | 16 +++++++ 3 files changed, 164 insertions(+) diff --git a/drivers/spi/espi-amd-core.c b/drivers/spi/espi-amd-core.c index 3704cbd816ae..18bfd2ca2316 100644 --- a/drivers/spi/espi-amd-core.c +++ b/drivers/spi/espi-amd-core.c @@ -114,6 +114,8 @@ static int amd_espi_alloc_cmd_data(struct espi_txcmd *cmd) case GET_CONFIGURATION: case IN_BAND_RESET: size = 1; + break; + case PERIPHERAL_CHNL: default: break; } @@ -710,6 +712,99 @@ void amd_espi_disable_io_decode_range(struct amd_espi *amd_espi, u32 io_range) writel(io_mmio_dc_enable, (ESPI_BASE + AMD_ESPI_SLAVE0_DECODE_EN_REG)); } +static int is_port_address_valid(struct amd_espi *amd_espi, struct periph_io_rw *msg_io) +{ + struct io_mmio_decode_config io_conf; + u16 port_end_addr = msg_io->port + msg_io->len - 1; + + amd_espi_get_io_mmio_decode_info(amd_espi, &io_conf); + + if (msg_io->port >= io_conf.range0.base_addr_range0 && + (port_end_addr <= ((u16)io_conf.range0.base_addr_range0 + + io_conf.range2.io_range0_size))) { + if (!(io_conf.io_mmio_dc_enable & IO_DECODE_RANGE0)) { + dev_err(amd_espi->dev, "IO range0 not enabled for port address: 0x%x\n", + msg_io->port); + return -EINVAL; + } + } else if ((msg_io->port >= io_conf.range0.base_addr_range1) && + (port_end_addr <= ((u16)io_conf.range0.base_addr_range1 + + io_conf.range2.io_range1_size))) { + if (!(io_conf.io_mmio_dc_enable & IO_DECODE_RANGE1)) { + dev_err(amd_espi->dev, "IO range1 not enabled for port address: 0x%x\n", + msg_io->port); + return -EINVAL; + } + } else if ((msg_io->port >= io_conf.range1.base_addr_range2) && + (port_end_addr <= ((u16)io_conf.range1.base_addr_range2 + + io_conf.range2.io_range2_size))) { + if (!(io_conf.io_mmio_dc_enable & IO_DECODE_RANGE2)) { + dev_err(amd_espi->dev, "IO range2 not enabled for port address: 0x%x\n", + msg_io->port); + return -EINVAL; + } + } else if ((msg_io->port >= io_conf.range1.base_addr_range3) && + (port_end_addr <= ((u16)io_conf.range1.base_addr_range3 + + io_conf.range2.io_range3_size))) { + if (!(io_conf.io_mmio_dc_enable & IO_DECODE_RANGE3)) { + dev_err(amd_espi->dev, "IO range3 not enabled for port address: 0x%x\n", + msg_io->port); + return -EINVAL; + } + } else { + dev_err(amd_espi->dev, "Port address 0x%x is invalid\n", msg_io->port); + return -EINVAL; + } + + return CB_SUCCESS; +} + +int amd_espi_periph_io_write(struct amd_espi *amd_espi, struct periph_io_rw *msg_io) +{ + if (is_port_address_valid(amd_espi, msg_io) != CB_SUCCESS) + return -EINVAL; + + switch (msg_io->len) { + case 1: + outb(msg_io->data.data_b, msg_io->port); + break; + case 2: + outw(msg_io->data.data_w, msg_io->port); + break; + case 4: + outl(msg_io->data.data_l, msg_io->port); + break; + default: + dev_err(amd_espi->dev, "Length of IO packet is not valid\n"); + return -EINVAL; + } + + return CB_SUCCESS; +} + +int amd_espi_periph_io_read(struct amd_espi *amd_espi, struct periph_io_rw *msg_io) +{ + if (is_port_address_valid(amd_espi, msg_io) != CB_SUCCESS) + return -EINVAL; + + switch (msg_io->len) { + case 1: + msg_io->data.data_b = inb(msg_io->port); + break; + case 2: + msg_io->data.data_w = inw(msg_io->port); + break; + case 4: + msg_io->data.data_l = inl(msg_io->port); + break; + default: + dev_err(amd_espi->dev, "Length of IO packet is not valid\n"); + return -EINVAL; + } + + return CB_SUCCESS; +} + static int amd_espi_get_master_cap(struct amd_espi *amd_espi, struct espi_master *master) { u32 master_cap_reg, info; diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index 31fb06f4a3ff..184ffdad4a48 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -325,6 +325,53 @@ static int amd_espi_ioctl_enable_io_decode_conf(struct amd_espi *amd_espi, unsig return ret; } +static int amd_espi_ioctl_io_write(struct amd_espi *amd_espi, unsigned long arg) +{ + struct periph_io_rw *message_io; + int ret; + + message_io = kzalloc(sizeof(*message_io), GFP_KERNEL); + if (!message_io) + return -ENOMEM; + + if (copy_from_user(message_io, (void __user *)arg, sizeof(struct periph_io_rw))) { + ret = -EFAULT; + goto io_write_free; + } + + ret = amd_espi_periph_io_write(amd_espi, message_io); + +io_write_free: + kfree(message_io); + return ret; +} + +static int amd_espi_ioctl_io_read(struct amd_espi *amd_espi, unsigned long arg) +{ + struct periph_io_rw *message_io; + int ret; + + message_io = kzalloc(sizeof(*message_io), GFP_KERNEL); + if (!message_io) + return -ENOMEM; + + if (copy_from_user(message_io, (void __user *)arg, sizeof(struct periph_io_rw))) { + ret = -EFAULT; + goto io_read_free; + } + + ret = amd_espi_periph_io_read(amd_espi, message_io); + if (ret != CB_SUCCESS) + goto io_read_free; + + if (copy_to_user((void __user *)arg, message_io, sizeof(struct periph_io_rw))) + ret = -EFAULT; + +io_read_free: + kfree(message_io); + return ret; +} + static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct amd_espi *amd_espi = filp->private_data; @@ -369,6 +416,12 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar } amd_espi_disable_io_decode_range(amd_espi, io_range); break; + case ESPI_IO_WRITE: + ret = amd_espi_ioctl_io_write(amd_espi, arg); + break; + case ESPI_IO_READ: + ret = amd_espi_ioctl_io_read(amd_espi, arg); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index ae76243786f0..4c67aa9f45a6 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -176,6 +176,8 @@ #define ESPI_GET_IODECODE_CONFIG _IOWR(ESPI_MAGIC_NUMBER, 0x7, struct io_mmio_decode_config) #define ESPI_EN_IODECODE_CONFIG _IOWR(ESPI_MAGIC_NUMBER, 0x8, struct io_mmio_decode_config) #define ESPI_DS_IODECODE_CONFIG _IOWR(ESPI_MAGIC_NUMBER, 0x9, u32) +#define ESPI_IO_WRITE _IOWR(ESPI_MAGIC_NUMBER, 0xa, struct periph_io_rw) +#define ESPI_IO_READ _IOWR(ESPI_MAGIC_NUMBER, 0xb, struct periph_io_rw) /* * enum amd_espi_versions - eSPI controller versions @@ -368,6 +370,18 @@ struct io_mmio_decode_config { union mmio_target_range5 mmio_range5; }; +union io_data { + u8 data_b; + u16 data_w; + u32 data_l; +}; + +struct periph_io_rw { + u8 len; + u16 port; + union io_data data; +} __packed; + /* Function prototypes */ int amd_espi_device_create(struct amd_espi *amd_espi, struct device *dev); void amd_espi_device_remove(struct amd_espi *amd_espi); @@ -388,4 +402,6 @@ void amd_espi_get_io_mmio_decode_info(struct amd_espi *amd_espi, void amd_espi_set_io_mmio_decode_config(struct amd_espi *amd_espi, struct io_mmio_decode_config *config); void amd_espi_disable_io_decode_range(struct amd_espi *amd_espi, u32 io_range); +int amd_espi_periph_io_write(struct amd_espi *amd_espi, struct periph_io_rw *message_io); +int amd_espi_periph_io_read(struct amd_espi *amd_espi, struct periph_io_rw *message_io); #endif From patchwork Thu Mar 13 18:34:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raju Rangoju X-Patchwork-Id: 14015784 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2069.outbound.protection.outlook.com [40.107.244.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FF8E1F3BB3; Thu, 13 Mar 2025 18:36:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.244.69 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890988; cv=fail; b=QjTIUCOowDKI1191N2IOoEE7ntLQ4Q5sMqB1vIRgAOLrUYFT0qed4sHn68fXDYFb2Um/z21lMNu42Jk99yFiUhg0mnWzI73uFU6jBgdz62+xy4DzfMsN22AvTjX7B9M93vdFgMW4+o6qkM+CtthhGcXoVhn+Gj2k8nO6KdDrEAQ= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741890988; c=relaxed/simple; bh=qCHbn0jljENjFOTYbv5MDM3F4Zbo+q/vwYYlQW6/E5o=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ghd2j+ItO2/1T1FMA3YFjM/EROZZLQs3/13+PMGknXS+t4HEOpXvmLhqVkr8jUJ0eFjG/pcm34XZniYDF2Cwh14mZPtgLbXtGeE+o6eE88KK9uXGm4FQVZ8AjfOoQ2HevEbEexgLzC97yscajsubyZE/tbRsdQn1kP+dnPWZw+A= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=QimfJAUb; arc=fail smtp.client-ip=40.107.244.69 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="QimfJAUb" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=UKG/r0Xuh2M+F08b0jbjHrqAxBwhtohGboMAzVdVxkQrAnqEH01VTmXbcxa8tbBZmGYq6L4jfmOEqddLSkxhZmyUK5wAXdMxe/3JX4x/pv75lwvv0pXF4vKM2EtOkInMQqA8HTlnLn3ioH8WrFpLFiu+GcDoOwR+DoqsoqeoXRRkrWzxQxefBJuguJv4gnhbquENPf6GkJ3Z9MnWyR1jEsFswU5zqgb+VavZNELOeDyacwXlGGkm8GNI+EEqv1/blvoSnqZZBeNH9XGVBb79p74LlIEHY9aW3yWDMAfpwIjJ2R1LBmeh9gAk85a3c0oGFG2AX1NjZJYQIm2+tjiW6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=M/NGWAQb2kMafGowR5NVG9VlftpZtSA/BYQHec2dauw=; b=urLcot3mzCdyP3jH9GwZEYSXAk61eFFszC2PAI4c3boo0YLvYZdEgpZqDWjqTGEHfTg5T47HCwG4NvkZzs0Ine6pgAtbNqRLNrQtvJLnq01uhnp/4i++8JBlAuJuikW6AL1wi90JHnI4tzv3EVRk/x404PZWGF5WBC629Grh5esx0K4K3P5cmWMJinIzDXICqxPa3oxn/UTuJ+HtYG2bZkGzBdZwIwzzSrXYiloX7mp17IsE2GDja7Y9CLRH5ZLEph3hvPXDQAVLE2yOblW72U+41uyHpJ0/Qi5I2Fyru4Wsjd8ny+oWDOafiOstybUmsXItxqe0ALFW4ZtPIb1mXw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=kernel.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=M/NGWAQb2kMafGowR5NVG9VlftpZtSA/BYQHec2dauw=; b=QimfJAUbRd2uJHEWxHpbw6FpcstQ1HYxOhuHsjhaLSY8icFxd8AUt/3usbWrKFjd1bfAGFYaJEbLy4ved/gIoydwupUMJ7QxHHF58AlYL3RoNIvkcNnFu1Ijf29sp5gYPMpAraWFiPWj/RGt3dCRkThGEqhEqCqz3rgsoD2+Q8U= Received: from SA9PR11CA0030.namprd11.prod.outlook.com (2603:10b6:806:6e::35) by SA1PR12MB6704.namprd12.prod.outlook.com (2603:10b6:806:254::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8511.27; Thu, 13 Mar 2025 18:36:22 +0000 Received: from SN1PEPF000397B2.namprd05.prod.outlook.com (2603:10b6:806:6e:cafe::c5) by SA9PR11CA0030.outlook.office365.com (2603:10b6:806:6e::35) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.8534.28 via Frontend Transport; Thu, 13 Mar 2025 18:36:22 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C Received: from SATLEXMB04.amd.com (165.204.84.17) by SN1PEPF000397B2.mail.protection.outlook.com (10.167.248.56) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.8534.20 via Frontend Transport; Thu, 13 Mar 2025 18:36:22 +0000 Received: from airavat.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Thu, 13 Mar 2025 13:36:20 -0500 From: Raju Rangoju To: , , CC: , , Subject: [PATCH 10/10] spi: espi_amd: Add eSPI PC channel MMIO read/write IOCTL commands Date: Fri, 14 Mar 2025 00:04:40 +0530 Message-ID: <20250313183440.261872-11-Raju.Rangoju@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250313183440.261872-1-Raju.Rangoju@amd.com> References: <20250313183440.261872-1-Raju.Rangoju@amd.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN1PEPF000397B2:EE_|SA1PR12MB6704:EE_ X-MS-Office365-Filtering-Correlation-Id: 42409f58-a5ff-4f0b-db99-08dd625df43e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|36860700013|1800799024|376014; X-Microsoft-Antispam-Message-Info: 3UG0GgNZDNfz7vdZ/tGZbSa9+2lbBOG9cXX+IsbQ5pKBMAWr/bY1F9+3SLHkA/xZHnf/wYyXF5NJZkb89MWCytfckoViWn+sqwICRO9L3bMkeor1R4HG0JNEOcpTmVnyLMF1QV6PfuNUTl+aKTRAV1cKjZQbaSlpl4CYU2T4TRMbUyearI+udbe8HeDaP/5Qn9wnsh6mURcy7NY+0By9jS5JPQ4Tuk83dbA6Uq2pUIjbT5nE8H2LJUiStij/ute75OqS2Ly0FGc9/qR0nfieG0ET5d9Yh+gwHaGA8Y7EK06Yj4RSvqK6I/doxakLoLaPXib3GlIAJ/5DrPVMH3Qm7dEZ7PtVkw/94h/sgBcD8NST1LK1UEbdZoahgnJmgPs0P5+JigN856Sp1q3tnFoWjlbU+7VPZOTVdUMEdK99kFJTtDdws57BqbdI1iGUUnHiCoU/6IArq9qUB73+E96E3M0JvOBjRdmldN6g0wcWN00jTnjjTrFKgnLbbNN6VIA2xoBIn9YerARZoaDEiCYXavYNq07f0cBkI/UsmvKGR1d5zQiEmsnmZV8Oa7SiVq1eA8GH5hVW0zREZAmfqfsLYS9ZGE8wu+zxEgAA3KTk0uqGoBgIzLlcTnsGmHlzMYzPxOUlXRYDp96hK1YpLUUZ3var4aEJDhD1zhD6kdpOpxy5zXUC25Ab09Gh6Mm/KvGvvrKlnA32jlh8c38irQHBXa6s6C9TEvXuA+5vuOw1/U+8tSp9A87BwUT7Ojk+moyPQgUgfHYX0QtAqSfssOtVtJqdBQEw73ay/8MU7xcInNXODL8qyrS7i0La4KeD8nwfa3vSIfObspYJJcmDBzWzeGt3FZ7+x7HlBYaE4LlJMffBjjQuTrnN08iQsNCnPvBWQe7zAbh0lYvEpze3+hKM16yo1XckMjhpCfPDjA42iqCXMJJD6Br6rTnREGDgMzlSa6qhIDRDmL1uC2puwledGPj4wcC6kF5hy9NY/C4h415tZ2XB1XOwWo+qnW/GFyu/ySCtp2MWSegeOueLZ0ZoyEsAIwgkBfNay6qRwrNIzPh9icmPGv9cLtI+wQpb0o28Q6PB91GfaK1aWMnQFXXuwTg5S3peTnFm8MVf6Yy2Q3prskjXkWbH9y6ZGuWUpVYreSwl6KS0N0H1PrNPk18KsAKIWkvvlOQG+T7ingbeVInGUC3I7WkpYHoj0XY0mRbFfPZlpMlB08D+3AnJdc/V8MwAEkKrK6/Nh0PDe98laHn77Al4aspzunNaNU+urNmVLuy4LqORNJdY0v+ebtqNpk+Vp++7zYMA9MO4r3EwYeUo5eavX6bYRmzfouDpmkcRErn37N9APHle1TubQJtAHuuaF6rWcA1IbsORtKa2gW0RHdoKEc9C7muMzrb77CxS8KMx0c+TOdxUquh8jCQ8h9IUu5XnNmIAkHyJtEu6KZLcvkAIjylsoVJ1efxOrKNknU2ObSxEHcJK7RJQO1+weQ== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(36860700013)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Mar 2025 18:36:22.5094 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 42409f58-a5ff-4f0b-db99-08dd625df43e X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: SN1PEPF000397B2.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR12MB6704 Add new IOCTL commands to perform eSPI peripheral channel(PC) MMIO read/write operations with eSPI slave0. The changes include validation of MMIO address ranges before initiating the read/write operations. Co-developed-by: Krishnamoorthi M Signed-off-by: Krishnamoorthi M Co-developed-by: Akshata MukundShetty Signed-off-by: Akshata MukundShetty Signed-off-by: Raju Rangoju --- drivers/spi/espi-amd-core.c | 80 +++++++++++++++++++++++++++++++++++++ drivers/spi/espi-amd-dev.c | 53 ++++++++++++++++++++++++ drivers/spi/espi-amd.h | 9 +++++ 3 files changed, 142 insertions(+) diff --git a/drivers/spi/espi-amd-core.c b/drivers/spi/espi-amd-core.c index 18bfd2ca2316..31069e86c704 100644 --- a/drivers/spi/espi-amd-core.c +++ b/drivers/spi/espi-amd-core.c @@ -805,6 +805,86 @@ int amd_espi_periph_io_read(struct amd_espi *amd_espi, struct periph_io_rw *msg_ return CB_SUCCESS; } +static int is_mmio_address_valid(struct amd_espi *amd_espi, struct periph_mem_rw *mem_data) +{ + struct io_mmio_decode_config io_conf; + u32 mmio_end_addr = mem_data->addr + 3; + + amd_espi_get_io_mmio_decode_info(amd_espi, &io_conf); + if (mem_data->addr >= io_conf.mmio_target_range0 && + (mmio_end_addr <= ((u32)io_conf.mmio_target_range0 + + io_conf.mmio_range4.mmio_range0_size))) { + if (!(io_conf.io_mmio_dc_enable & MMIO_DECODE_RANGE0)) { + dev_err(amd_espi->dev, "MMIO range0 not enabled for address: 0x%x\n", + mem_data->addr); + return -EINVAL; + } + } else if ((mem_data->addr >= io_conf.mmio_target_range1) && + (mmio_end_addr <= ((u32)io_conf.mmio_target_range1 + + io_conf.mmio_range4.mmio_range1_size))) { + if (!(io_conf.io_mmio_dc_enable & MMIO_DECODE_RANGE1)) { + dev_err(amd_espi->dev, "MMIO range1 not enabled for address: 0x%x\n", + mem_data->addr); + return -EINVAL; + } + } else if ((mem_data->addr >= io_conf.mmio_target_range2) && + (mmio_end_addr <= ((u32)io_conf.mmio_target_range2 + + io_conf.mmio_range5.mmio_range2_size))) { + if (!(io_conf.io_mmio_dc_enable & MMIO_DECODE_RANGE2)) { + dev_err(amd_espi->dev, "MMIO range2 not enabled for address: 0x%x\n", + mem_data->addr); + return -EINVAL; + } + } else if ((mem_data->addr >= io_conf.mmio_target_range3) && + (mmio_end_addr <= ((u32)io_conf.mmio_target_range3 + + io_conf.mmio_range5.mmio_range3_size))) { + if (!(io_conf.io_mmio_dc_enable & MMIO_DECODE_RANGE3)) { + dev_err(amd_espi->dev, "MMIO range3 not enabled for address: 0x%x\n", + mem_data->addr); + return -EINVAL; + } + } else { + dev_err(amd_espi->dev, "Address 0x%x is invalid\n", mem_data->addr); + return -EINVAL; + } + + return CB_SUCCESS; +} + +int amd_espi_periph_mem_write(struct amd_espi *amd_espi, struct periph_mem_rw *mem_data) +{ + void __iomem *mmio_addr; + + if (is_mmio_address_valid(amd_espi, mem_data) != CB_SUCCESS) + return -EINVAL; + + mmio_addr = ioremap(mem_data->addr, 4); + if (!mmio_addr) + return -ENOMEM; + + writel(mem_data->data, mmio_addr); + iounmap(mmio_addr); + + return CB_SUCCESS; +} + +int amd_espi_periph_mem_read(struct amd_espi *amd_espi, struct periph_mem_rw *mem_data) +{ + void __iomem *mmio_addr; + + if (is_mmio_address_valid(amd_espi, mem_data) != CB_SUCCESS) + return -EINVAL; + + mmio_addr = ioremap(mem_data->addr, 4); + if (!mmio_addr) + return -ENOMEM; + + mem_data->data = readl(mmio_addr); + iounmap(mmio_addr); + + return CB_SUCCESS; +} + static int amd_espi_get_master_cap(struct amd_espi *amd_espi, struct espi_master *master) { u32 master_cap_reg, info; diff --git a/drivers/spi/espi-amd-dev.c b/drivers/spi/espi-amd-dev.c index 184ffdad4a48..7e4477dd17e5 100644 --- a/drivers/spi/espi-amd-dev.c +++ b/drivers/spi/espi-amd-dev.c @@ -372,6 +372,53 @@ static int amd_espi_ioctl_io_read(struct amd_espi *amd_espi, unsigned long arg) return ret; } +static int amd_espi_ioctl_mem_write(struct amd_espi *amd_espi, unsigned long arg) +{ + struct periph_mem_rw *mem_data; + int ret; + + mem_data = kzalloc(sizeof(*mem_data), GFP_KERNEL); + if (!mem_data) + return -ENOMEM; + + if (copy_from_user(mem_data, (void __user *)arg, sizeof(struct periph_mem_rw))) { + ret = -EFAULT; + goto mem_write_free; + } + + ret = amd_espi_periph_mem_write(amd_espi, mem_data); + +mem_write_free: + kfree(mem_data); + return ret; +} + +static int amd_espi_ioctl_mem_read(struct amd_espi *amd_espi, unsigned long arg) +{ + struct periph_mem_rw *mem_data; + int ret; + + mem_data = kzalloc(sizeof(*mem_data), GFP_KERNEL); + if (!mem_data) + return -ENOMEM; + + if (copy_from_user(mem_data, (void __user *)arg, sizeof(struct periph_mem_rw))) { + ret = -EFAULT; + goto mem_read_free; + } + + ret = amd_espi_periph_mem_read(amd_espi, mem_data); + if (ret != CB_SUCCESS) + goto mem_read_free; + + if (copy_to_user((void __user *)arg, mem_data, sizeof(struct periph_mem_rw))) + ret = -EFAULT; + +mem_read_free: + kfree(mem_data); + return ret; +} + static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct amd_espi *amd_espi = filp->private_data; @@ -422,6 +469,12 @@ static long amd_espi_ioctl(struct file *filp, unsigned int cmd, unsigned long ar case ESPI_IO_READ: ret = amd_espi_ioctl_io_read(amd_espi, arg); break; + case ESPI_MEM_WRITE: + ret = amd_espi_ioctl_mem_write(amd_espi, arg); + break; + case ESPI_MEM_READ: + ret = amd_espi_ioctl_mem_read(amd_espi, arg); + break; default: dev_err(amd_espi->dev, "ESPI command not found, returning error\n"); ret = -EINVAL; diff --git a/drivers/spi/espi-amd.h b/drivers/spi/espi-amd.h index 4c67aa9f45a6..9e084bec8ff5 100644 --- a/drivers/spi/espi-amd.h +++ b/drivers/spi/espi-amd.h @@ -178,6 +178,8 @@ #define ESPI_DS_IODECODE_CONFIG _IOWR(ESPI_MAGIC_NUMBER, 0x9, u32) #define ESPI_IO_WRITE _IOWR(ESPI_MAGIC_NUMBER, 0xa, struct periph_io_rw) #define ESPI_IO_READ _IOWR(ESPI_MAGIC_NUMBER, 0xb, struct periph_io_rw) +#define ESPI_MEM_WRITE _IOWR(ESPI_MAGIC_NUMBER, 0xc, struct periph_mem_rw) +#define ESPI_MEM_READ _IOWR(ESPI_MAGIC_NUMBER, 0xd, struct periph_mem_rw) /* * enum amd_espi_versions - eSPI controller versions @@ -382,6 +384,11 @@ struct periph_io_rw { union io_data data; } __packed; +struct periph_mem_rw { + u32 addr; + u32 data; +}; + /* Function prototypes */ int amd_espi_device_create(struct amd_espi *amd_espi, struct device *dev); void amd_espi_device_remove(struct amd_espi *amd_espi); @@ -404,4 +411,6 @@ void amd_espi_set_io_mmio_decode_config(struct amd_espi *amd_espi, void amd_espi_disable_io_decode_range(struct amd_espi *amd_espi, u32 io_range); int amd_espi_periph_io_write(struct amd_espi *amd_espi, struct periph_io_rw *message_io); int amd_espi_periph_io_read(struct amd_espi *amd_espi, struct periph_io_rw *message_io); +int amd_espi_periph_mem_write(struct amd_espi *amd_espi, struct periph_mem_rw *mem_data); +int amd_espi_periph_mem_read(struct amd_espi *amd_espi, struct periph_mem_rw *mem_data); #endif