From nobody Tue Sep 9 21:28:52 2025 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10on2045.outbound.protection.outlook.com [40.107.92.45]) (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 A8848242D94; Fri, 5 Sep 2025 08:42:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.92.45 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061746; cv=fail; b=ZKuSKXFltSaoUZ7B7vpapJqcFewDALs/BFSz486M5VtKekznByX1tAfCA3ZGsTiKhqY0Yr90rIe12Oz7f69Z7U5k05IB5jdDZgvW2bubKLv6fEnPM9+AXjkSJ3W4/1AQRnAY+5orsl71a6h8je8fp7AbM31m9m1uAC0xYiNWDgk= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061746; c=relaxed/simple; bh=jYly6ZleG/OcBcmWMeY+/uWfdasUegqOOn7RTcs/Ftg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pw48S+INPqkBxH9+YG4UK74G8KSh4CUV0J+tE8dpNgYyKGcKMjPAnenh78f3O8mEsOvqyUwXLmooC1o1SWmSE9R3T3lR62DUipwUFtbwiMmHDmCb/RtJP0VOZj0GJk8qPQo7fmIzWAQle7Jzl44hgRkMcPWfW8eIPMxy0UmdCj4= 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=n8/Z0uFe; arc=fail smtp.client-ip=40.107.92.45 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="n8/Z0uFe" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=LO4/edQqSD2Mgyqdl+L70sel2jFWMbpqUjhiWauc498O/VcTk6AB6dnu8YSHSZ+6W2lNO7Cr7zThgTkEW904qWuzzETbKASOVKUd2JNBCOlQUucvbkgi0RYG+eNWipQyyp7YXZ/x/6R415qm2t17OwAqgVdWYxSb70Kjb766ymxg7qosAYEejXdjTeXnWQJDbu9eyKbzdqpOnJY/SyvKl85e53pyvaWbe6mRKIXKTXzWHw8n19FNpoaxZZx22fjYNypcK/O4WPSVekm6jbwW1vwKQ5yNTuBryVAT/ABaYH+QJVkro3nqNJYShQ75RQlksDBM1QYonNu2KpAlgNkL8w== 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=vddh5gddId5gR3KRmIpxOiG/9jAlua4VlomritJy708=; b=LhSlXne033FntnDcBRHwJYnCqMmRiLyV8Ye8QQpDtSqxl3vpSmfibOM6vjk+WYJIfpfrbfVXD1hBmwx/uOccyzz/zw2uLkVf+qOujlEvfVPk8aeAhFow1Zs/n0dEvmQON4dckTH8bUB/MMLgNcT5WN4KO9sYwr6kBzuYyLrymYidWYeVCr5Xn1yaHarJIY10emOmM9NAZqDDkpIeNWsj2ahHpYWfHCK/RjrWSFxdstPxVYa26iPQTouAOQMaERFY5+ybAWrufWtbi9feahKBfYr3vYMkZL+sVxSuspR1tJu3yGama4EGGOrKKNQwJsr/L0Bkso9vvD/tnPbk2pvvcA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.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=vddh5gddId5gR3KRmIpxOiG/9jAlua4VlomritJy708=; b=n8/Z0uFe8sbuMcg/KeDsT7CfoLo4iMjaDVEO7i/PKqQQQHICwns6XZyj0okdj6AUt56uRDrj5IWYsbvoXgBJKxB42nx9NiadiNieKpkui61Qi9BLs7Z5HlsCtMKxK6m4KWwKjWBU6oTK00IEXRH0LcReymFliIkDjyHShS9QEJQ= Received: from SJ0PR05CA0052.namprd05.prod.outlook.com (2603:10b6:a03:33f::27) by SJ1PR12MB6123.namprd12.prod.outlook.com (2603:10b6:a03:45a::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9094.19; Fri, 5 Sep 2025 08:42:20 +0000 Received: from CO1PEPF000075EE.namprd03.prod.outlook.com (2603:10b6:a03:33f:cafe::60) by SJ0PR05CA0052.outlook.office365.com (2603:10b6:a03:33f::27) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9094.16 via Frontend Transport; Fri, 5 Sep 2025 08:42:20 +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=SATLEXMB03.amd.com; pr=C Received: from SATLEXMB03.amd.com (165.204.84.17) by CO1PEPF000075EE.mail.protection.outlook.com (10.167.249.37) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9094.14 via Frontend Transport; Fri, 5 Sep 2025 08:42:20 +0000 Received: from SATLEXMB06.amd.com (10.181.40.147) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 5 Sep 2025 03:42:05 -0500 Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB06.amd.com (10.181.40.147) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 5 Sep 2025 03:42:02 -0500 Received: from localhost (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 via Frontend Transport; Fri, 5 Sep 2025 03:42:01 -0500 From: Michal Simek To: , , , CC: Salih Erim , Anand Ashok Dumbre , Anish Kadamathikuttiyil Karthikeyan Pillai , Andy Shevchenko , Conor Dooley , David Lechner , Jonathan Cameron , "Krzysztof Kozlowski" , =?UTF-8?q?Nuno=20S=C3=A1?= , Rob Herring , "open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" , "open list:IIO SUBSYSTEM AND DRIVERS" Subject: [PATCH 1/6] dt-bindings: iio: xilinx: Add Documentation for Sysmon Date: Fri, 5 Sep 2025 10:41:44 +0200 Message-ID: <610690b9cc4ab3854b56df550b688b4cc72a5653.1757061697.git.michal.simek@amd.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7036; i=michal.simek@amd.com; h=from:subject:message-id; bh=oAK+tV50H6FxUNTxxyMRovdkHdQp5LFNhGxk7RtAZNM=; b=owGbwMvMwCG2mv3fB7+vgl8ZT6slMWTsWuRjInqBVWH9SluB/bGxs9mD393csonLwPpHrYNbh pNOZdipjlIWBjEOBlkxRZbpTDoOa75dWyq2PDIfZg4rE8gQBi5OAZiIxT2Gv1Lv0hJeHl/GfaPz 1d/tD3WyBFN/KexdcHOezN+JmxweK1cz/OFu3pxjendt2dI0pjV7K34dChTTnuecP3PTKiFzhlU 8k1kB X-Developer-Key: i=michal.simek@amd.com; a=openpgp; fpr=67350C9BF5CCEE9B5364356A377C7F21FE3D1F91 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CO1PEPF000075EE:EE_|SJ1PR12MB6123:EE_ X-MS-Office365-Filtering-Correlation-Id: 9f82d205-0114-49f7-f944-08ddec582082 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|82310400026|376014|36860700013|1800799024|13003099007; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?gpO6to8T4i38S4QOXsIVKYhehiiV92FDnoMYE018AYda5GnB3IL43aV3CuR7?= =?us-ascii?Q?jpt7fQrDIgH4xbqAfcua9llZPcbIdthPJ2wDSFhINQzYCJK8t0q5tUSEY3M8?= =?us-ascii?Q?j9NG91EILAq46bEqGUjzdmrLw56n11R9F/NaDS4H99IKUn1GmPM+L4cLMUrW?= =?us-ascii?Q?4NllBM5O0qY5tJBez9GAU/cpf7ZRc3mSE8mpCMTS0MxnaiipLI+OtEhUWKei?= =?us-ascii?Q?/4I5FN/l8GkC87sZMZ844trQaN7Qw/hDVVGjzXzRGxuwYFq2HbJd1bn3HjH5?= =?us-ascii?Q?B6y6ohqA2EUUB0HlOHO/pUeT+ELk69ztdo3BDITwT7u1th2Uxjxd4qEVwPja?= =?us-ascii?Q?E7dsdGVZScAx+D1sKItsEsVt+jVn4Qwxo7UCNxLTeBOb2vYP846j8Gh+d0y8?= =?us-ascii?Q?2znuHZOuajM4XcNbZfns/aGE+9cLkcy55lbYbvSFOLBs8hu+tLtjAuKd8Y4j?= =?us-ascii?Q?vuRJwhWoeIhEPeJF13ckcH14sNHBcQRB6049uRGbfov3+I4SMRGkXNoTNK9Y?= =?us-ascii?Q?z4rDW1a5Znl4tcoSLOnhm0BuaHVO9HD2AISLP7XpIJH3Wc70+Z9LL3B37PtO?= =?us-ascii?Q?KpIuvtXvOrk2OFlld/MriDrr/jrtq0BDW7YQ4VE6rYtsyWbh3qmj7cLpmfmn?= =?us-ascii?Q?bfkt06SgfIdzrxlrGDTMYx/HfwPEFW7h+kHJ2RflYAHH8yhJS4/qVbprR5JS?= =?us-ascii?Q?GYkP0I3tx3mc9fOWjqNwt1vDBvUZJufxrhYfxTRFRc6EX35OFKacN6PNS0RP?= =?us-ascii?Q?cIKBumdzvnAEKY1HGdKeL0c/P01utGMp9h0IOjCO+3DWnTnh2SkU+imtWjiR?= =?us-ascii?Q?zjZjqYR7HMMSDKElRK/1p4aNLk007GRzSJ+6teUyfzf0oOoeXRvugc4rm+Xa?= =?us-ascii?Q?97BPtiHktkkPjHvXZcjaT1/YH4wP3Qomd3VhW4iiwir6Pm5hrlxAT2g7S9rH?= =?us-ascii?Q?c9ARfyI8b+N5t7QR6UHvbvPJox5uHjZyyDyrhJ5hGO19pIDJQfLIh1uJLf9Q?= =?us-ascii?Q?Z1GF6bOSsDIqV1dpa7qSKf6jmWWnfhB1VA7iTIEtqUnH4Acs1mLHjTa5pvda?= =?us-ascii?Q?a9eksTgZ0bK3fmk7yF9QSMqGxx34fH/Pak4l+s+ZpAejHbqp1NvyRnGSdxYx?= =?us-ascii?Q?h00cLZh4Aift9O4nmxVlsVipXWwgFKLfgHzQDrcTEolF+0IEjB5/u8Bxpg2B?= =?us-ascii?Q?qMtTZcikJJY9usBOSFEwCFl/M22AT358+ULu3uGGElDeXI4b8U3GP8oa/N8b?= =?us-ascii?Q?DVWf+KLJURvXhQkYexXU/0QF8A/FweqJb3sc0/37OnxIsG342V9sp1hOwj3t?= =?us-ascii?Q?//kclbsioRn/rZwj3Kr+mm34v59K8AK20a9/t7FlkBjAcDj9CiuDi/BEBzWa?= =?us-ascii?Q?lPgMV7FXHaJN94iNcd3VryB56IudtHuHBvjEksRe8gMd58/hxHt1NfiQ6m+Q?= =?us-ascii?Q?PCA6FQZEj8LhSIfasURNUOuGlk049k2Hqt6ZShUt9PPWuXq6kV8wSg=3D=3D?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB03.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(7416014)(82310400026)(376014)(36860700013)(1800799024)(13003099007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2025 08:42:20.1857 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9f82d205-0114-49f7-f944-08ddec582082 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=[SATLEXMB03.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CO1PEPF000075EE.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ1PR12MB6123 Content-Type: text/plain; charset="utf-8" From: Salih Erim Add devicetree documentation for Xilinx Sysmon IP which is used for internal chip monitoring on Xilinx Versal SOCs. Co-developed-by: Anand Ashok Dumbre Signed-off-by: Anand Ashok Dumbre Co-developed-by: Anish Kadamathikuttiyil Karthikeyan Pillai Signed-off-by: Anish Kadamathikuttiyil Karthikeyan Pillai Signed-off-by: Salih Erim Signed-off-by: Michal Simek --- .../bindings/iio/adc/xlnx,versal-sysmon.yaml | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/xlnx,versal-s= ysmon.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/xlnx,versal-sysmon.y= aml b/Documentation/devicetree/bindings/iio/adc/xlnx,versal-sysmon.yaml new file mode 100644 index 000000000000..a768395cade7 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/xlnx,versal-sysmon.yaml @@ -0,0 +1,235 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/xlnx,versal-sysmon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Versal Sysmon + +maintainers: + - Salih Erim + +description: + The Xilinx Sysmon provides on-chip monitoring and control for the supply + voltages and temperatures across the chip. Since there are only 160 supp= ly + voltage registers and 184 measurement points, there is no constant mappi= ng + of supply voltage registers and the measurement points. User has to sele= ct + the voltages to monitor in design tool. Depending on the selection, a vo= ltage + supply gets mapped to one of the supply registers. So, this mapping info= rmation + is provided via description which contain the information of name of + the supply enabled and the supply register it maps to. + +properties: + compatible: + items: + - const: xlnx,versal-sysmon + + reg: + maxItems: 1 + description: Sysmon Registers. + + interrupts: + maxItems: 1 + description: Interrupt line for Sysmon. + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + '#io-channel-cells': + const: 0 + + xlnx,hbm: + type: boolean + description: + Exists if node refers to a HBM (High Bandwidth Memory) SLR (Super Lo= gic Region). + + xlnx,nodeid: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + PLM specified sysmon node id. + + xlnx,numaiechannels: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 64 + description: + Total number of sysmon satellites close to AI Engine exposed as chan= nels. + + xlnx,numchannels: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 1 + maximum: 160 + description: + Number of supply channels enabled in the design. + +patternProperties: + "^supply@([0-9]{1,2}|1[0-5][0-9])$": + type: object + description: + Represents the supplies configured in the design. + + properties: + reg: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 159 + description: + The supply number associated with the voltage. + + xlnx,name: + $ref: /schemas/types.yaml#/definitions/string + description: + Name of the supply enabled + + xlnx,bipolar: + $ref: /schemas/types.yaml#/definitions/flag + description: + If the supply has a bipolar type and the output will be signed. + + required: + - reg + - xlnx,name + + additionalProperties: false + + "^temp@([1-9]|[1-5][0-9]|6[0-4])$": + type: object + description: + Represents the sysmon temperature satellites. + + properties: + reg: + minimum: 1 + maximum: 64 + description: + The sysmon temperature satellite number. + + xlnx,aie-temp: + $ref: /schemas/types.yaml#/definitions/flag + description: + If present it indicates the temperature satellite is in + close proximity with AI Engine + + xlnx,name: + $ref: /schemas/types.yaml#/definitions/string + description: + Name of temperature satellite exposed + + required: + - reg + - xlnx,name + + additionalProperties: false + +required: + - compatible + - reg + - xlnx,numchannels + +additionalProperties: false + +examples: + - | + #include + sysmon@f1270000 { + compatible =3D "xlnx,versal-sysmon"; + reg =3D <0xf1270000 0x4000>; + interrupts =3D <0 0x90 IRQ_TYPE_LEVEL_HIGH>; + xlnx,numchannels =3D <8>; + xlnx,numaiechannels =3D <8>; + xlnx,nodeid =3D <0x18224055>; + #address-cells =3D <1>; + #size-cells =3D <0>; + supply@0 { + reg =3D <0>; + xlnx,name =3D "vccint"; + }; + + supply@31 { + reg =3D <31>; + xlnx,name =3D "vccsoc"; + }; + + supply@32 { + reg =3D <32>; + xlnx,bipolar; + xlnx,name =3D "vccram"; + }; + + supply@63 { + reg =3D <63>; + xlnx,bipolar; + xlnx,name =3D "vccaux"; + }; + + supply@64 { + reg =3D <64>; + xlnx,name =3D "vccbram"; + }; + + supply@95 { + reg =3D <95>; + xlnx,name =3D "gt_avaux"; + }; + + supply@96 { + reg =3D <96>; + xlnx,name =3D "gt_vccaux"; + }; + + supply@159 { + reg =3D <159>; + xlnx,name =3D "vccint_ir"; + }; + + temp@7 { + reg =3D <7>; + xlnx,aie-temp; + xlnx,name =3D "aie-temp-ch0"; + }; + + temp@8 { + reg =3D <8>; + xlnx,aie-temp; + xlnx,name =3D "aie-temp-ch1"; + }; + + temp@14 { + reg =3D <14>; + xlnx,aie-temp; + xlnx,name =3D "aie-temp-ch2"; + }; + + temp@15 { + reg =3D <15>; + xlnx,aie-temp; + xlnx,name =3D "aie-temp-ch3"; + }; + + temp@16 { + reg =3D <16>; + xlnx,aie-temp; + xlnx,name =3D "aie-temp-ch4"; + }; + + temp@30 { + reg =3D <30>; + xlnx,aie-temp; + xlnx,name =3D "aie-temp-ch5"; + }; + + temp@33 { + reg =3D <33>; + xlnx,aie-temp; + xlnx,name =3D "aie-temp-ch6"; + }; + + temp@34 { + reg =3D <34>; + xlnx,aie-temp; + xlnx,name =3D "aie-temp-ch7"; + }; + }; --=20 2.43.0 From nobody Tue Sep 9 21:28:52 2025 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2052.outbound.protection.outlook.com [40.107.244.52]) (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 E3F64280337; Fri, 5 Sep 2025 08:42:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.244.52 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061752; cv=fail; b=DXCQZjjrmGJEWlfd0ZzTV0+bZLTi60S24+i+Dw/9SvC2gWvzT7GYVts5R+7+3cUYc5FV1WQzWSfN1oagM3OriRI6curR8APzJf1ONLUKC6L0udvwTSEnXLKqws7riPscAheVEMHRTXx3U4dxFlpClx5SwljHCmQo9IA/PswMsyw= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061752; c=relaxed/simple; bh=DF/yuYoFujCJRkydvsNVVVonVgbTGo7eQRouTPsDXzg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=C12UzwvQLBOg+6taNk2YlnvzpEPOsL1yxb2Bdp78vZ1KUhlFQuIQ4BWA7ab8fUjY3zsb8A+unzQGLsoOd63mEfmZRfh5/slegtsRKHQOJSH9TlOZ9Slf3A5foOb+YuQeWVjaGHrLOCivIEwa2zjyA/TUzyEQzJ/LRb6RWCRn3EA= 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=OvcgfjhX; arc=fail smtp.client-ip=40.107.244.52 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="OvcgfjhX" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=l/PO36vhfPr2MH5tCsC0Jo3Xj1g/wjQnxx8gMtku4OHPHWOkJRzAojMwHsxpmspxix4GGFbBAW4DEPun5UcqlkKX8M51NEDvD1F8BiQuBtbzNNq8GXK5xiTxrsk7TrI47K2ND/FdmMPydJqBNerKAhUP79gWFtlGkiO/YUaQcI5Ki/3Nych7D8GsbftWpVk5JI1aER3eFWI7CjVEXnjL4oBJ6io5F/hcVsYd9j7R3RDrvE0eFi++wDw85SBMTfeY5K18vPzxX6Ql9UcZeBvYgohekoV3a5FDxbTwQrC6hKbjsfvXEZqgW1PBgrCITd3PWdjeoykuxygoMkOnPpJ9iA== 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=wApK5aA2rXU2dc+sa4VQ12BEggcCX1b1J5SLPbSn5ME=; b=GEODXR1NFW5pGd0dDf8UG+adv2Dwhofu9fWgEanQigq8IEqRkkDRsdkYxRUZLMj+f7iIG0+9meM65Rl9vIPpDbnf7ItDW8NctU9v5M94GoaN0oVUG+QxxsEB7vHEn//z3KqDjBxAxxW3Lt9O1o+WxeHpH2mNrRskAjDJH6SWlNmE2vWqyhNHZWfS44iUZtU8F5BOeJyYOc4WwSseGuh8cVH45l5Q59RZDMXq9dV0fPCVfj2k3FRsWK5IZi7yG6FoIMkbpOTAZm4y1QA64G3N1LF2VZX3e6jY2uZ2zqUoyWRk0ATCinxL3TBkRlvbOejodo3dgsqOOlOOC1FBbPa2tg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.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=wApK5aA2rXU2dc+sa4VQ12BEggcCX1b1J5SLPbSn5ME=; b=OvcgfjhXEgqcFSizHpNFoesTOcNzZqrMRfIDxxsUY3OCi3ifBKHj8Ka/6c3Trk83twuM4JTHEmZ0X4aMAQVHiuFYHs62v1tGWATXPvkEwnU+NCHM3VpBInr52Furd63aLVm6Rt9OQTKLlDpOzIuH8o3R54X5lcCcTKgrtFf5oRA= Received: from SJ0PR13CA0057.namprd13.prod.outlook.com (2603:10b6:a03:2c2::32) by SJ1PR12MB6075.namprd12.prod.outlook.com (2603:10b6:a03:45e::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9073.27; Fri, 5 Sep 2025 08:42:23 +0000 Received: from SJ5PEPF000001EB.namprd05.prod.outlook.com (2603:10b6:a03:2c2:cafe::3a) by SJ0PR13CA0057.outlook.office365.com (2603:10b6:a03:2c2::32) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9115.6 via Frontend Transport; Fri, 5 Sep 2025 08:42:23 +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 SJ5PEPF000001EB.mail.protection.outlook.com (10.167.242.199) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9094.14 via Frontend Transport; Fri, 5 Sep 2025 08:42:23 +0000 Received: from SATLEXMB04.amd.com (10.181.40.145) 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; Fri, 5 Sep 2025 03:42:05 -0500 Received: from localhost (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 via Frontend Transport; Fri, 5 Sep 2025 03:42:04 -0500 From: Michal Simek To: , , , CC: Salih Erim , Anand Ashok Dumbre , Andy Shevchenko , "David Lechner" , Jonathan Cameron , =?UTF-8?q?Nuno=20S=C3=A1?= , "open list:IIO SUBSYSTEM AND DRIVERS" Subject: [PATCH 2/6] iio: versal-sysmon: add driver for Versal Sysmon Date: Fri, 5 Sep 2025 10:41:45 +0200 Message-ID: <2780986977702f126416ec442c5336bd541f475b.1757061697.git.michal.simek@amd.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=61112; i=michal.simek@amd.com; h=from:subject:message-id; bh=vd/A2w/i51GYHy2uTWwv8Jr47QawunMHtWZTiIzKyeE=; b=owGbwMvMwCG2mv3fB7+vgl8ZT6slMWTsWuS7hf2MA/+D3felpR5xxZtaTlBlnWOc/0BgXve32 vgUjYfaHaUsDGIcDLJiiizTmXQc1ny7tlRseWQ+zBxWJpAhDFycAjAR4wKGPxz/ZZ8nWpT6mCfp ZS8J+fi34KL38YO7m6XPfnzytv3DETlGhjVeCYViBqoaqsLHhNR+bq5R3z1h6dY+x2slsl+trPu ecwMA X-Developer-Key: i=michal.simek@amd.com; a=openpgp; fpr=67350C9BF5CCEE9B5364356A377C7F21FE3D1F91 Content-Transfer-Encoding: quoted-printable Received-SPF: None (SATLEXMB04.amd.com: michal.simek@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EB:EE_|SJ1PR12MB6075:EE_ X-MS-Office365-Filtering-Correlation-Id: c1d2ef55-0cca-4746-19b0-08ddec582273 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: =?us-ascii?Q?B9HLng7x3deUyo37gM+vvwtJOHAjylzxlnM6GkwwQECJz2J+6R+/3XBN0y1X?= =?us-ascii?Q?yATmcgWktLNqa33m+zdGDQiCLQTMvGBtvd+jdtOZENMv2k4KXUiXQdIlI9dD?= =?us-ascii?Q?694a6dfC/bdhw3NUEJuJ4NW9blw5K99tbSdtRzps5erKQy3yHBNWv5+ECrwh?= =?us-ascii?Q?qflsgH7NWDXOl9rY6WO771ExToLyfz9w0OGaZkhHwUnN3cFTQDhHzobvFYXr?= =?us-ascii?Q?3Isc+Q/K1Eg291brb7/mlOd6FwpQDpNE+rwRTDusXDDZ5Fde0Eq9sUAmkcp1?= =?us-ascii?Q?6fTnjNkOM8Sp/JMz2wEt4ZtoZaGHBbg0FRei1+X4uXFnu8dUFbssJTg28z8m?= =?us-ascii?Q?2Ct8lFHfqFeEesvBOSRceVt66o1B8S7Pu+wbTEnU6kw4k9FpSvy+Ycucnipx?= =?us-ascii?Q?LHsKH7AJZi2Xq8p4ys7axoqtRB1TO+lhfaURYWo2SGHMUtkM9ye1YZquBrZa?= =?us-ascii?Q?EcfdUBmGikNccpZsQIUvPQreEO2owGHMRLaRHCUhr+surVJlWAC3ZscVFOJX?= =?us-ascii?Q?HimXvOJiLk26WKUCD0n5z7gjGkJ31cKzDqOZ58I78bS/5GA01iGPc8fXgghs?= =?us-ascii?Q?gm4Y3DAQ+KRbY/pd/5SdSjkLOWn3tAGa8JEWXAaynEuFLwztw0NiYgEWnmbY?= =?us-ascii?Q?hrBE43JGGKOc9Sfa8DpmOtfp3Jsw7sbrrnHsc5F99NPkiCDZ0E0dVazD61/Y?= =?us-ascii?Q?0KV2jzUfrsG0VjSg8XCbk3eiRjV895Tct96N02R4PVvHo0UltSYJ5V3eVs1C?= =?us-ascii?Q?eMKJVb2DDsSHgLixpHDkmwZTGA7ux6RupCkKxccblXY+2yE6P/2ipLl2rYxH?= =?us-ascii?Q?BGT3Pgo3QpNhz4nyBp6CbIapC/I2yUH2+9vX7T/hIoriZsWBxfPVwUTcKzZ9?= =?us-ascii?Q?uCNIvRmBMbFNz/XATfo2+QgaUOuy7F7ebNUNtGFneqqLJabnUoETdWhU7cFo?= =?us-ascii?Q?YXvqEfjGaiZZ5Sa9gLEh/fK+Kziuy/6QQJrV/ztRQRBlKm69MbpOzV2E2Xp7?= =?us-ascii?Q?itS+akz2CA33zIC8tki6EjvD5E25V6CkjQF8Xx3xn3Ni+rA00yxw7oT0eCPv?= =?us-ascii?Q?yoZiVt7FLpn4LAOzMPl722w7sNzOk8MyuLd5LPOZtnaul6cGmIls+OGlhyxQ?= =?us-ascii?Q?C1MN88l8NmI4G1aCRNLMER6aogyXrhnOYN2thiTXA4H4+cgtdN5vZLLAhyBu?= =?us-ascii?Q?7und5OB7S43IgQv+x0tIbUOAkYgxrAN+7rheYfdDsKR6kUq86l3+17yKWZPH?= =?us-ascii?Q?4akE0Fm83dTMBjLeV5STMxOHtyZ+z8KBqI0K1QtUAtkxiQ4ek0ZnUctOfYD9?= =?us-ascii?Q?WslyyqkOT4esGySR3j1ah99jIoxo7rWfOP+VJ+7vKnbxV8XJFBv5nYrhPayo?= =?us-ascii?Q?1432ixppk2abhCfzoZv4uSytc13mvcJmmAtYLDaiTo9oDi9mFbPm34IvFmiJ?= =?us-ascii?Q?L0U2Heb/TNWQ1MIM3j0Xgus4fZ6vwmrPiGcOHw4WeHqtvfac+WeCPYaKD2n1?= =?us-ascii?Q?Bv1NG6ZIRMkGEVwUrjCSag6uHKS95lo7GZrB?= 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: 05 Sep 2025 08:42:23.4367 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c1d2ef55-0cca-4746-19b0-08ddec582273 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: SJ5PEPF000001EB.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ1PR12MB6075 Content-Type: text/plain; charset="utf-8" From: Salih Erim Sysmon Driver uses Linux IIO framework, which was used to abstract the supply voltages and temperatures across the chip as Voltage and Temperature Channels in the framework. Since there are only 160 supply voltage registers and 184 measurement points, there is no constant mapping of supply voltage registers and the measurement points. User has to select the voltages to monitor in design tool. Depending on the selection, a voltage supply gets mapped to one of the supply registers. So, this mapping information is provided to the driver via a device tree. Depending on the number of supplies enabled in the design, the device tree will contain the information of name of the supply enabled and the supply register it maps to. Co-developed-by: Anand Ashok Dumbre Signed-off-by: Anand Ashok Dumbre Signed-off-by: Salih Erim Signed-off-by: Michal Simek --- MAINTAINERS | 7 + drivers/iio/adc/Kconfig | 15 + drivers/iio/adc/Makefile | 2 + drivers/iio/adc/versal-sysmon-core.c | 1334 ++++++++++++++++++ drivers/iio/adc/versal-sysmon.c | 264 ++++ drivers/iio/adc/versal-sysmon.h | 275 ++++ include/linux/iio/adc/versal-sysmon-events.h | 56 + 7 files changed, 1953 insertions(+) create mode 100644 drivers/iio/adc/versal-sysmon-core.c create mode 100644 drivers/iio/adc/versal-sysmon.c create mode 100644 drivers/iio/adc/versal-sysmon.h create mode 100644 include/linux/iio/adc/versal-sysmon-events.h diff --git a/MAINTAINERS b/MAINTAINERS index fe168477caa4..1a9c5549d0dc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -27602,6 +27602,13 @@ F: Documentation/misc-devices/xilinx_sdfec.rst F: drivers/misc/xilinx_sdfec.c F: include/uapi/misc/xilinx_sdfec.h =20 +XILINX VERSAL SYSMON DRIVER +M: Salih Erim +S: Maintained +F: Documentation/devicetree/bindings/iio/adc/xlnx,versal-sysmon.yaml +F: drivers/iio/adc/versal-sysmon* +F: include/linux/iio/adc/versal-sysmon-events.h + XILINX UARTLITE SERIAL DRIVER M: Peter Korsgaard L: linux-serial@vger.kernel.org diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 6de2abad0197..7021ba4f5f12 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1821,4 +1821,19 @@ config XILINX_AMS The driver can also be built as a module. If so, the module will be cal= led xilinx-ams. =20 +config VERSAL_SYSMON_CORE + tristate + +config VERSAL_SYSMON + tristate "Xilinx Sysmon driver for Versal" + depends on HAS_IOMEM + select VERSAL_SYSMON_CORE + help + Say yes here to have support for the Xilinx Sysmon. + The driver will enable users to monitor temperature and voltage on the + Xilinx Versal platform. + + The driver can also be build as a module. If so, the module will be cal= led + versal-sysmon. + endmenu diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 1c6ca5fd4b6d..2d29c3e60101 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -159,3 +159,5 @@ obj-$(CONFIG_VIPERBOARD_ADC) +=3D viperboard_adc.o obj-$(CONFIG_XILINX_AMS) +=3D xilinx-ams.o xilinx-xadc-y :=3D xilinx-xadc-core.o xilinx-xadc-events.o obj-$(CONFIG_XILINX_XADC) +=3D xilinx-xadc.o +obj-$(CONFIG_VERSAL_SYSMON_CORE) +=3D versal-sysmon-core.o +obj-$(CONFIG_VERSAL_SYSMON) +=3D versal-sysmon.o diff --git a/drivers/iio/adc/versal-sysmon-core.c b/drivers/iio/adc/versal-= sysmon-core.c new file mode 100644 index 000000000000..21b6a413dccb --- /dev/null +++ b/drivers/iio/adc/versal-sysmon-core.c @@ -0,0 +1,1334 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Xilinx SYSMON for Versal + * + * Copyright (C) 2019 - 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc. + * + * Description: + * This driver is developed for SYSMON on Versal. The driver supports INDI= O Mode + * and supports voltage and temperature monitoring via IIO sysfs interface= and + * in kernel event monitoring for some modules. + */ + +#include +#include "versal-sysmon.h" + +#define SYSMON_EVENT_WORK_DELAY_MS 1000 +#define SYSMON_UNMASK_WORK_DELAY_MS 500 + +#define SYSMON_FRACTIONAL_SHIFT 7U + +#define SYSMON_HBM_TEMP_SHIFT 16U +#define SYSMON_HBM_TEMP_MASK GENMASK(6, 0) + +/* This structure describes temperature events */ +static const struct iio_event_spec sysmon_temp_events[] =3D { + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_RISING, + .mask_separate =3D BIT(IIO_EV_INFO_VALUE), + }, + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_FALLING, + .mask_separate =3D BIT(IIO_EV_INFO_VALUE), + }, + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_EITHER, + .mask_separate =3D + BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_HYSTERESIS), + }, +}; + +/* This structure describes voltage events */ +static const struct iio_event_spec sysmon_supply_events[] =3D { + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_RISING, + .mask_separate =3D BIT(IIO_EV_INFO_VALUE), + }, + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_FALLING, + .mask_separate =3D BIT(IIO_EV_INFO_VALUE), + }, + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_EITHER, + .mask_separate =3D BIT(IIO_EV_INFO_ENABLE), + }, +}; + +/* Temperature channel attributes */ +static const struct iio_chan_spec temp_channels[] =3D { + SYSMON_CHAN_TEMP(TEMP_MAX, "temp"), + SYSMON_CHAN_TEMP(TEMP_MIN, "min"), + SYSMON_CHAN_TEMP(TEMP_MAX_MAX, "max_max"), + SYSMON_CHAN_TEMP(TEMP_MIN_MIN, "min_min"), +}; + +/* Temperature event attributes */ +static const struct iio_chan_spec temp_events[] =3D { + SYSMON_CHAN_TEMP_EVENT(TEMP_EVENT, "temp", sysmon_temp_events), + SYSMON_CHAN_TEMP_EVENT(OT_EVENT, "ot", sysmon_temp_events), +}; + +/* HBM temperature channel attributes */ +static const struct iio_chan_spec temp_hbm_channels[] =3D { + SYSMON_CHAN_TEMP_HBM(TEMP_HBM, "temp_hbm"), +}; + +int sysmon_read_reg(struct sysmon *sysmon, u32 offset, u32 *data) +{ + return sysmon->ops->read_reg(sysmon, offset, data); +} +EXPORT_SYMBOL(sysmon_read_reg); + +void sysmon_write_reg(struct sysmon *sysmon, u32 offset, u32 data) +{ + sysmon->ops->write_reg(sysmon, offset, data); +} +EXPORT_SYMBOL(sysmon_write_reg); + +static void sysmon_update_reg(struct sysmon *sysmon, u32 offset, u32 mask,= u32 data) +{ + sysmon->ops->update_reg(sysmon, offset, mask, data); +} + +static u32 sysmon_temp_offset(int address) +{ + switch (address) { + case TEMP_MAX: + return SYSMON_TEMP_MAX; + case TEMP_MIN: + return SYSMON_TEMP_MIN; + case TEMP_MAX_MAX: + return SYSMON_TEMP_MAX_MAX; + case TEMP_MIN_MIN: + return SYSMON_TEMP_MIN_MIN; + case TEMP_HBM: + return SYSMON_TEMP_HBM; + default: + return -EINVAL; + } + return -EINVAL; +} + +static u32 sysmon_temp_thresh_offset(int address, enum iio_event_direction= dir) +{ + switch (address) { + case TEMP_EVENT: + return (dir =3D=3D IIO_EV_DIR_RISING) ? SYSMON_TEMP_TH_UP : + SYSMON_TEMP_TH_LOW; + case OT_EVENT: + return (dir =3D=3D IIO_EV_DIR_RISING) ? SYSMON_OT_TH_UP : + SYSMON_OT_TH_LOW; + default: + return -EINVAL; + } + return -EINVAL; +} + +static u32 sysmon_supply_offset(int address) +{ + return (address * 4) + SYSMON_SUPPLY_BASE; +} + +static u32 sysmon_supply_thresh_offset(int address, + enum iio_event_direction dir) +{ + if (dir =3D=3D IIO_EV_DIR_RISING) + return (address * 4) + SYSMON_SUPPLY_TH_UP; + else if (dir =3D=3D IIO_EV_DIR_FALLING) + return (address * 4) + SYSMON_SUPPLY_TH_LOW; + + return -EINVAL; +} + +/** + * sysmon_hbm_to_millicelsius() - The raw register value to milliDeg Celsi= us. + * @raw_data: Raw register value + * @val: The numerator of the fraction needed by IIO_VAL_INT + * @val2: Denominator of the fraction needed by IIO_VAL_INT + * + * The function returns a fraction which returns milliDeg celsius + */ +static void sysmon_hbm_to_millicelsius(int raw_data, int *val, int *val2) +{ + *val =3D ((raw_data >> SYSMON_HBM_TEMP_SHIFT) & SYSMON_HBM_TEMP_MASK) * + SYSMON_MILLI_SCALE; + *val2 =3D 0; +} + +/** + * sysmon_q8p7_to_millicelsius() - converts fixed point Q8.7 format to a f= raction. + * @raw_data: Raw ADC value + * @val: The numerator of the fraction needed by IIO_VAL_INT + * @val2: Denominator of the fraction needed by IIO_VAL_INT + * + * The function returns a fraction which returns milliDeg Celsius + */ +static void sysmon_q8p7_to_millicelsius(int raw_data, int *val, int *val2) +{ + *val =3D (((raw_data & 0x8000) ? -(twoscomp(raw_data)) : raw_data) * + SYSMON_MILLI_SCALE) >> SYSMON_FRACTIONAL_SHIFT; + *val2 =3D 0; +} + +/** + * sysmon_millicelsius_to_q8p7() - converts value from IIO Framework to AD= C Raw data + * @raw_data: Raw ADC value + * @val: The numerator of the fraction provided by the IIO Framework + * @val2: Denominator of the fraction provided by the IIO Framework + * + * The function takes in exponent and mantissa as val and val2 respectively + * of temperature value in milliDeg Celsius and returns raw adc value for = the + * given temperature. + */ +static void sysmon_millicelsius_to_q8p7(u32 *raw_data, int val, int val2) +{ + (void)val2; + + *raw_data =3D (val << SYSMON_FRACTIONAL_SHIFT) / SYSMON_MILLI_SCALE; +} + +static void sysmon_supply_rawtoprocessed(int raw_data, int *val, int *val2) +{ + int mantissa, format, exponent; + + mantissa =3D raw_data & SYSMON_MANTISSA_MASK; + exponent =3D 16 - ((raw_data & SYSMON_MODE_MASK) >> SYSMON_MODE_SHIFT); + format =3D (raw_data & SYSMON_FMT_MASK) >> SYSMON_FMT_SHIFT; + + if (format && (mantissa >> SYSMON_MANTISSA_SIGN_SHIFT)) { + *val =3D ((~(mantissa) & SYSMON_MANTISSA_MASK) * + (-1 * SYSMON_MILLI_SCALE)) >> exponent; + } else { + *val =3D (mantissa * SYSMON_MILLI_SCALE) >> exponent; + } + + *val2 =3D 0; +} + +static void sysmon_supply_processedtoraw(int val, int val2, u32 reg_val, + u32 *raw_data) +{ + int exponent =3D (reg_val & SYSMON_MODE_MASK) >> SYSMON_MODE_SHIFT; + int format =3D (reg_val & SYSMON_FMT_MASK) >> SYSMON_FMT_SHIFT; + int scale =3D 1 << (16 - exponent); + int tmp; + + tmp =3D (val * scale) / SYSMON_MILLI_SCALE; + + /* Set out of bound values to saturation levels */ + if (format) { + if (tmp > SYSMON_UPPER_SATURATION_SIGNED) + tmp =3D 0x7fff; + else if (tmp < SYSMON_LOWER_SATURATION_SIGNED) + tmp =3D 0x8000; + + } else { + if (tmp > SYSMON_UPPER_SATURATION) + tmp =3D 0xffff; + else if (tmp < SYSMON_LOWER_SATURATION) + tmp =3D 0x0000; + } + + *raw_data =3D tmp & 0xffff; +} + +static int sysmon_osr_write(struct sysmon *sysmon, + int channel_type, int val) +{ + u32 mask, shift; + + if (channel_type =3D=3D IIO_TEMP) { + mask =3D SYSMON_TEMP_SAT_CONFIG_MASK; + shift =3D SYSMON_TEMP_SAT_CONFIG_SHIFT; + } else if (channel_type =3D=3D IIO_VOLTAGE) { + mask =3D SYSMON_SUPPLY_CONFIG_MASK; + shift =3D SYSMON_SUPPLY_CONFIG_SHIFT; + } else { + return -EINVAL; + } + + sysmon_update_reg(sysmon, SYSMON_CONFIG, mask, (val << shift)); + + return 0; +} + +static int sysmon_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct sysmon *sysmon =3D iio_priv(indio_dev); + u32 offset, regval; + u32 ret =3D -EINVAL; + + mutex_lock(&sysmon->mutex); + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_TEMP: + offset =3D sysmon_temp_offset(chan->address); + *val =3D sysmon->temp_read(sysmon, offset); + *val2 =3D 0; + ret =3D IIO_VAL_INT; + break; + + case IIO_VOLTAGE: + offset =3D sysmon_supply_offset(chan->address); + sysmon_read_reg(sysmon, offset, ®val); + *val =3D (int)regval; + *val2 =3D 0; + ret =3D IIO_VAL_INT; + break; + + default: + break; + } + break; + + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_TEMP: + /* In Deg C */ + offset =3D sysmon_temp_offset(chan->address); + regval =3D sysmon->temp_read(sysmon, offset); + if (!sysmon->hbm_slr) + sysmon_q8p7_to_millicelsius(regval, val, val2); + else + sysmon_hbm_to_millicelsius(regval, val, val2); + + ret =3D IIO_VAL_INT; + break; + + case IIO_VOLTAGE: + /* In Volts */ + offset =3D sysmon_supply_offset(chan->address); + sysmon_read_reg(sysmon, offset, ®val); + sysmon_supply_rawtoprocessed(regval, val, val2); + ret =3D IIO_VAL_INT; + break; + + default: + break; + } + break; + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + switch (chan->type) { + case IIO_TEMP: + *val =3D sysmon->temp_oversampling; + ret =3D IIO_VAL_INT; + break; + + case IIO_VOLTAGE: + *val =3D sysmon->supply_oversampling; + ret =3D IIO_VAL_INT; + break; + + default: + break; + } + break; + + default: + break; + } + + mutex_unlock(&sysmon->mutex); + return ret; +} + +static int sysmon_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct sysmon *sysmon =3D iio_priv(indio_dev); + u32 ret =3D -EINVAL; + int i; + + mutex_lock(&sysmon->mutex); + switch (mask) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + if (val2 !=3D 0) + break; + + switch (chan->type) { + case IIO_TEMP: + for (i =3D 0; i < sysmon->oversampling_num; i++) { + if (val =3D=3D sysmon->oversampling_avail[i]) { + ret =3D sysmon_osr_write(sysmon, + IIO_TEMP, val); + if (!ret) + sysmon->temp_oversampling =3D val; + } + } + break; + + case IIO_VOLTAGE: + for (i =3D 0; i < sysmon->oversampling_num; i++) { + if (val =3D=3D sysmon->oversampling_avail[i]) { + ret =3D sysmon_osr_write(sysmon, + IIO_VOLTAGE, val); + if (!ret) + sysmon->supply_oversampling =3D val; + } + } + break; + + default: + break; + } + break; + default: + break; + } + + mutex_unlock(&sysmon->mutex); + return ret; +} + +static int sysmon_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct sysmon *sysmon; + + if (mask !=3D IIO_CHAN_INFO_OVERSAMPLING_RATIO) + return -EINVAL; + + sysmon =3D iio_priv(indio_dev); + + *vals =3D sysmon->oversampling_avail; + *length =3D sysmon->oversampling_num; + *type =3D IIO_VAL_INT; + + return IIO_AVAIL_LIST; +} + +static int sysmon_get_event_mask(unsigned long address) +{ + if (address =3D=3D TEMP_EVENT) + return BIT(SYSMON_BIT_TEMP); + else if (address =3D=3D OT_EVENT) + return BIT(SYSMON_BIT_OT); + + /* return supply */ + return BIT(address / 32); +} + +static int sysmon_read_alarm_config(struct sysmon *sysmon, + unsigned long address) +{ + u32 reg_val; + u32 shift =3D REG32_SHIFT(address); + u32 offset =3D SYSMON_ALARM_REG + REG32_OFFSET(address); + + sysmon_read_reg(sysmon, offset, ®_val); + + return reg_val & BIT(shift); +} + +static void sysmon_write_alarm_config(struct sysmon *sysmon, + unsigned long address, u32 val) +{ + u32 shift =3D REG32_SHIFT(address); + u32 offset =3D SYSMON_ALARM_REG + REG32_OFFSET(address); + + sysmon_update_reg(sysmon, offset, BIT(shift), (val << shift)); +} + +static int sysmon_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct sysmon *sysmon =3D iio_priv(indio_dev); + u32 config_value, imr; + u32 alarm_event_mask =3D sysmon_get_event_mask(chan->address); + + sysmon_read_reg(sysmon, SYSMON_IMR, &imr); + + /* Getting the unmasked interrupts */ + imr =3D ~imr; + + if (chan->type =3D=3D IIO_VOLTAGE) { + config_value =3D sysmon_read_alarm_config(sysmon, chan->address); + + return (config_value && (imr & alarm_event_mask)); + } + + return (imr & sysmon_get_event_mask(chan->address)) ? 1 : 0; +} + +static int sysmon_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, bool state) +{ + struct sysmon *sysmon =3D iio_priv(indio_dev); + u32 offset =3D SYSMON_ALARM_REG + REG32_OFFSET(chan->address); + u32 shift =3D REG32_SHIFT(chan->address); + u32 ier =3D sysmon_get_event_mask(chan->address); + u32 alarm_config; + unsigned long flags; + + mutex_lock(&sysmon->mutex); + spin_lock_irqsave(&sysmon->lock, flags); + + if (chan->type =3D=3D IIO_VOLTAGE) { + sysmon_write_alarm_config(sysmon, chan->address, state); + + sysmon_read_reg(sysmon, offset, &alarm_config); + + if (alarm_config & BIT(shift)) + sysmon_write_reg(sysmon, SYSMON_IER, ier); + else + sysmon_write_reg(sysmon, SYSMON_IDR, ier); + } else if (chan->type =3D=3D IIO_TEMP) { + if (state) { + sysmon_write_reg(sysmon, SYSMON_IER, ier); + sysmon->temp_mask &=3D ~ier; + } else { + sysmon_write_reg(sysmon, SYSMON_IDR, ier); + sysmon->temp_mask |=3D ier; + } + } + + spin_unlock_irqrestore(&sysmon->lock, flags); + mutex_unlock(&sysmon->mutex); + + return 0; +} + +static int sysmon_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int *val, + int *val2) +{ + struct sysmon *sysmon =3D iio_priv(indio_dev); + u32 offset, reg_val; + u32 mask, shift; + u32 ret =3D -EINVAL; + + mutex_lock(&sysmon->mutex); + if (chan->type =3D=3D IIO_TEMP) { + if (info =3D=3D IIO_EV_INFO_VALUE) { + offset =3D sysmon_temp_thresh_offset(chan->address, dir); + sysmon_read_reg(sysmon, offset, ®_val); + sysmon_q8p7_to_millicelsius(reg_val, val, val2); + ret =3D IIO_VAL_INT; + } else if (info =3D=3D IIO_EV_INFO_HYSTERESIS) { + mask =3D (chan->address =3D=3D OT_EVENT) ? 0x1 : 0x2; + shift =3D mask - 1; + sysmon_read_reg(sysmon, SYSMON_TEMP_EV_CFG, ®_val); + *val =3D (reg_val & mask) >> shift; + *val2 =3D 0; + ret =3D IIO_VAL_INT; + } + } else if (chan->type =3D=3D IIO_VOLTAGE) { + offset =3D sysmon_supply_thresh_offset(chan->address, dir); + sysmon_read_reg(sysmon, offset, ®_val); + sysmon_supply_rawtoprocessed(reg_val, val, val2); + ret =3D IIO_VAL_INT; + } + + mutex_unlock(&sysmon->mutex); + return ret; +} + +static int sysmon_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val, int val2) +{ + struct sysmon *sysmon =3D iio_priv(indio_dev); + u32 offset, raw_val, reg_val; + u32 mask, shift; + + mutex_lock(&sysmon->mutex); + if (chan->type =3D=3D IIO_TEMP) { + if (info =3D=3D IIO_EV_INFO_VALUE) { + offset =3D sysmon_temp_thresh_offset(chan->address, dir); + sysmon_millicelsius_to_q8p7(®_val, val, val2); + sysmon_write_reg(sysmon, offset, reg_val); + } else if (info =3D=3D IIO_EV_INFO_HYSTERESIS) { + /* calculating the mask value for OT and TEMP Alarms */ + mask =3D (chan->address =3D=3D OT_EVENT) ? 1 : 2; + shift =3D mask - 1; + sysmon_update_reg(sysmon, SYSMON_TEMP_EV_CFG, mask, + (val << shift)); + } + } else if (chan->type =3D=3D IIO_VOLTAGE) { + offset =3D sysmon_supply_thresh_offset(chan->address, dir); + sysmon_read_reg(sysmon, offset, ®_val); + sysmon_supply_processedtoraw(val, val2, reg_val, &raw_val); + sysmon_write_reg(sysmon, offset, raw_val); + } + + mutex_unlock(&sysmon->mutex); + return 0; +} + +static ssize_t supply_avg_en_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev_attr *this_attr =3D to_iio_dev_attr(attr); + struct iio_dev *indio_dev =3D dev_to_iio_dev(dev); + struct sysmon *sysmon =3D iio_priv(indio_dev); + int supply =3D this_attr->address; + u32 shift =3D REG32_SHIFT(supply); + u32 offset, reg_val; + + offset =3D SYSMON_SUPPLY_EN_AVG_OFFSET + REG32_OFFSET(supply); + sysmon_read_reg(sysmon, offset, ®_val); + + /* Return the bit state */ + return sprintf(buf, "%u\n", !!(reg_val & BIT(shift))); +} + +static ssize_t tempsat_avg_en_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev_attr *this_attr =3D to_iio_dev_attr(attr); + struct iio_dev *indio_dev =3D dev_to_iio_dev(dev); + struct sysmon *sysmon =3D iio_priv(indio_dev); + int tempsat =3D this_attr->address; + u32 shift =3D REG32_SHIFT(tempsat); + u32 offset, reg_val; + + offset =3D SYSMON_TEMP_SAT_EN_AVG_OFFSET + REG32_OFFSET(tempsat); + sysmon_read_reg(sysmon, offset, ®_val); + + /* Return the bit state */ + return sprintf(buf, "%u\n", !!(reg_val & BIT(shift))); +} + +static ssize_t supply_avg_en_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev_attr *this_attr =3D to_iio_dev_attr(attr); + struct iio_dev *indio_dev =3D dev_to_iio_dev(dev); + struct sysmon *sysmon =3D iio_priv(indio_dev); + int supply =3D this_attr->address; + u32 shift =3D REG32_SHIFT(supply); + unsigned long val; + u32 offset; + int ret; + + ret =3D kstrtoul(buf, 10, &val); + if (ret) + return ret; + + /* Ensure the input value is either 0 or 1 */ + val =3D !!val; + + offset =3D SYSMON_SUPPLY_EN_AVG_OFFSET + REG32_OFFSET(supply); + sysmon_update_reg(sysmon, offset, BIT(shift), (val << shift)); + + return len; +} + +static ssize_t tempsat_avg_en_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev_attr *this_attr =3D to_iio_dev_attr(attr); + struct iio_dev *indio_dev =3D dev_to_iio_dev(dev); + struct sysmon *sysmon =3D iio_priv(indio_dev); + int tempsat =3D this_attr->address; + u32 shift =3D REG32_SHIFT(tempsat); + unsigned long val; + u32 offset; + int ret; + + ret =3D kstrtoul(buf, 10, &val); + if (ret) + return ret; + + /* Ensure the input value is either 0 or 1 */ + val =3D !!val; + + offset =3D SYSMON_TEMP_SAT_EN_AVG_OFFSET + REG32_OFFSET(tempsat); + sysmon_update_reg(sysmon, offset, BIT(shift), (val << shift)); + + return len; +} + +static const struct iio_info iio_dev_info =3D { + .read_avail =3D sysmon_read_avail, + .read_raw =3D sysmon_read_raw, + .write_raw =3D sysmon_write_raw, + .read_event_config =3D sysmon_read_event_config, + .write_event_config =3D sysmon_write_event_config, + .read_event_value =3D sysmon_read_event_value, + .write_event_value =3D sysmon_write_event_value, +}; + +/* sysmon instance for in kernel exported functions */ +static struct sysmon *g_sysmon; + +void sysmon_set_iio_dev_info(struct iio_dev *indio_dev) +{ + indio_dev->info =3D &iio_dev_info; +} +EXPORT_SYMBOL(sysmon_set_iio_dev_info); +/** + * sysmon_register_temp_ops - register temperature based event handler for= a + * given region. + * @cb: callback function pointer. + * @data: private data to be passed to the callback. + * @region_id: id of the region for which the callback is to be set. + * @return: 0 for success and negative number in case of failure. + */ +int sysmon_register_temp_ops(void (*cb)(void *data, struct regional_node *= node), + void *data, enum sysmon_region region_id) +{ + struct sysmon *sysmon =3D g_sysmon; + struct region_info *region; + int ret =3D 0, found =3D 0; + + if (!cb || !sysmon) + return -EINVAL; + + ret =3D mutex_lock_interruptible(&sysmon->mutex); + if (ret) { + dev_err(sysmon->dev, "Failed to acquire a lock. Process was interrupted = by fatal signals"); + return ret; + } + + if (list_empty(&sysmon->region_list)) { + dev_err(sysmon->dev, "Failed to set a callback. HW node info missing in = the device tree/ Not supported for this device"); + ret =3D -EINVAL; + goto exit; + } + + list_for_each_entry(region, &sysmon->region_list, list) { + if (region->id =3D=3D region_id) { + found =3D 1; + if (region->cb) { + dev_err(sysmon->dev, "Error callback already set. Unregister the exist= ing callback to set a new one."); + ret =3D -EINVAL; + goto exit; + } + region->cb =3D cb; + region->data =3D data; + break; + } + } + + if (!found) { + dev_err(sysmon->dev, "Error invalid region. Please select the correct re= gion"); + ret =3D -EINVAL; + } + +exit: + mutex_unlock(&sysmon->mutex); + return ret; +} +EXPORT_SYMBOL(sysmon_register_temp_ops); + +/** + * sysmon_unregister_temp_ops - Unregister the callback for temperature + * notification. + * @region_id: id of the region for which the callback is to be set. + * @return: 0 for success and negative number in case of failure. + */ +int sysmon_unregister_temp_ops(enum sysmon_region region_id) +{ + struct sysmon *sysmon =3D g_sysmon; + struct region_info *region; + int ret =3D 0, found =3D 0; + + if (!sysmon) + return -EINVAL; + + ret =3D mutex_lock_interruptible(&sysmon->mutex); + if (ret) { + dev_err(sysmon->dev, "Failed to acquire a lock. Process was interrupted = by fatal signals"); + return ret; + } + + if (list_empty(&sysmon->region_list)) { + dev_err(sysmon->dev, "Failed to set a callback. HW node info missing in = the device tree/ Not supported for this device"); + ret =3D -EINVAL; + goto exit; + } + + list_for_each_entry(region, &sysmon->region_list, list) { + if (region->id =3D=3D region_id) { + found =3D 1; + region->cb =3D NULL; + region->data =3D NULL; + break; + } + } + + if (!found) { + dev_err(sysmon->dev, "Error no such region. Please select the correct re= gion"); + ret =3D -EINVAL; + } + +exit: + mutex_unlock(&sysmon->mutex); + return ret; +} +EXPORT_SYMBOL(sysmon_unregister_temp_ops); + +/** + * sysmon_nodes_by_region - returns the nodes list for a particular region. + * @region_id: id for the region for which nodes are requested. + * @return: Pointer to the linked list or NULL if region is not present. + */ +struct list_head *sysmon_nodes_by_region(enum sysmon_region region_id) +{ + struct sysmon *sysmon =3D g_sysmon; + struct region_info *region; + + if (!sysmon) + return NULL; + + list_for_each_entry(region, &sysmon->region_list, list) { + if (region->id =3D=3D region_id) + return ®ion->node_list; + } + + dev_err(sysmon->dev, "Error invalid region. Please select the correct reg= ion"); + + return NULL; +} +EXPORT_SYMBOL(sysmon_nodes_by_region); + +/** + * sysmon_get_node_value - returns value of the sensor at a node. + * @sat_id: id of the node. + * @return: -EINVAL if not initialized or returns raw value of the sensor. + */ +int sysmon_get_node_value(int sat_id) +{ + struct sysmon *sysmon =3D g_sysmon; + u32 raw; + + if (!sysmon) + return -EINVAL; + + sysmon_read_reg(sysmon, SYSMON_NODE_OFFSET, &raw); + + return raw; +} +EXPORT_SYMBOL(sysmon_get_node_value); + +static void sysmon_push_event(struct iio_dev *indio_dev, u32 address) +{ + u32 i; + const struct iio_chan_spec *chan; + + for (i =3D 0; i < indio_dev->num_channels; i++) { + if (indio_dev->channels[i].address =3D=3D address) { + chan =3D &indio_dev->channels[i]; + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(chan->type, + chan->channel, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(indio_dev)); + } + } +} + +int sysmon_create_avg_en_sysfs_entries(struct iio_dev *indio_dev) +{ + struct sysmon *sysmon =3D iio_priv(indio_dev); + int max_attrs_num, ret, i; + u8 supply_index; + + /* Allocate memory for temp. sat attribute list dynamically */ + sysmon->temp_avg_en_attrs =3D + devm_kzalloc(&indio_dev->dev, + SYSMON_TEMP_SAT_COUNT * + sizeof(*sysmon->temp_avg_en_attrs), GFP_KERNEL); + if (!sysmon->temp_avg_en_attrs) + return -ENOMEM; + + /* Allocate memory for supply attribute list dynamically */ + sysmon->supply_avg_en_attrs =3D + devm_kzalloc(&indio_dev->dev, + sysmon->num_supply_chan * + sizeof(*sysmon->supply_avg_en_attrs), GFP_KERNEL); + if (!sysmon->supply_avg_en_attrs) + return -ENOMEM; + + /* + * Maximum attribute number is max temp. satellite number plus + * enabled supply channel number. + */ + max_attrs_num =3D SYSMON_TEMP_SAT_COUNT + sysmon->num_supply_chan; + + sysmon->avg_attrs =3D devm_kzalloc(&indio_dev->dev, + (max_attrs_num + 1) * + sizeof(*sysmon->avg_attrs), GFP_KERNEL); + if (!sysmon->avg_attrs) + return -ENOMEM; + + for (i =3D 0; i < SYSMON_TEMP_SAT_COUNT; i++) { + /* + * Temp. satellites are indexed from 1 to 64 on the register + * mapping, so the attr. sysfs entry will have appropriate + * postfix index number, plus one, accordingly. We are adding + * loop index number to attributes address because enable bit + * fields starts from 0. + */ + sysmon->temp_avg_en_attrs[i].dev_attr.attr.name =3D + devm_kasprintf(&indio_dev->dev, GFP_KERNEL, + "averaging_en_tempsat%d", (i + 1)); + sysmon->temp_avg_en_attrs[i].dev_attr.attr.mode =3D 0644; + sysmon->temp_avg_en_attrs[i].dev_attr.show =3D tempsat_avg_en_show; + sysmon->temp_avg_en_attrs[i].dev_attr.store =3D tempsat_avg_en_store; + sysmon->temp_avg_en_attrs[i].address =3D i; + + /* Add all temp. sat averaging attrs to array of avg attributes */ + sysmon->avg_attrs[i] =3D + &sysmon->temp_avg_en_attrs[i].dev_attr.attr; + } + + for (i =3D 0; i < sysmon->num_supply_chan; i++) { + /* + * Even each Sysmon device has max. 160 supply/voltage + * channels, they are enabled by dt discretely. There is no + * point of create attributes for all supply channels. We only + * create which is enabled by design and reflected in dt as + * supply channels. Supply index values are address of the + * IIO channel. + */ + supply_index =3D indio_dev->channels[i].address; + sysmon->supply_avg_en_attrs[i].dev_attr.attr.name =3D + devm_kasprintf(&indio_dev->dev, GFP_KERNEL, + "averaging_en_supply%d", supply_index); + sysmon->supply_avg_en_attrs[i].dev_attr.attr.mode =3D 0644; + sysmon->supply_avg_en_attrs[i].dev_attr.show =3D supply_avg_en_show; + sysmon->supply_avg_en_attrs[i].dev_attr.store =3D supply_avg_en_store; + sysmon->supply_avg_en_attrs[i].address =3D supply_index; + + sysmon->avg_attrs[SYSMON_TEMP_SAT_COUNT + i] =3D + &sysmon->supply_avg_en_attrs[i].dev_attr.attr; + } + + /* Null-terminate the attribute array */ + sysmon->avg_attrs[max_attrs_num + 1] =3D NULL; + + /* + * Assign all dynamically created attributes to averaging + * attributes group with "averaging" name. It will create + * a subfolder for this group under the IIO device folder. + */ + sysmon->avg_attr_group.name =3D "averaging"; + sysmon->avg_attr_group.attrs =3D sysmon->avg_attrs; + + /* Create the sysfs group for the attributes */ + ret =3D sysfs_create_group(&indio_dev->dev.kobj, + &sysmon->avg_attr_group); + if (ret) { + dev_err(&indio_dev->dev, + "Failed to create averaging attribute group\n"); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(sysmon_create_avg_en_sysfs_entries); + +static void sysmon_region_event_handler(struct sysmon *sysmon) +{ + struct region_info *region; + struct regional_node *node, *eventnode; + u32 regval, event =3D 0; + u16 thresh_up, val; + + sysmon_read_reg(sysmon, SYSMON_TEMP_TH_UP, ®val); + thresh_up =3D (u16)regval; + + list_for_each_entry(region, &sysmon->region_list, list) { + list_for_each_entry(node, ®ion->node_list, + regional_node_list) { + val =3D sysmon_get_node_value(node->sat_id); + + /* Find the highest value */ + if (compare(val, thresh_up)) { + eventnode =3D node; + eventnode->temp =3D val; + thresh_up =3D val; + event =3D 1; + } + } + if (event && region->cb) + region->cb(region->data, eventnode); + } +} + +static void sysmon_handle_event(struct iio_dev *indio_dev, u32 event) +{ + struct sysmon *sysmon =3D iio_priv(indio_dev); + unsigned long alarm_flag_reg; + u32 address, bit, reg_val; + u32 alarm_flag_offset =3D SYSMON_ALARM_FLAG + (event * 4); + u32 alarm_reg_offset =3D SYSMON_ALARM_REG + (event * 4); + + switch (event) { + case SYSMON_BIT_TEMP: + address =3D TEMP_EVENT; + sysmon_push_event(indio_dev, address); + sysmon_write_reg(sysmon, SYSMON_IDR, BIT(SYSMON_BIT_TEMP)); + sysmon->masked_temp |=3D BIT(SYSMON_BIT_TEMP); + sysmon_region_event_handler(sysmon); + break; + + case SYSMON_BIT_OT: + address =3D OT_EVENT; + sysmon_push_event(indio_dev, address); + sysmon_write_reg(sysmon, SYSMON_IDR, BIT(SYSMON_BIT_OT)); + sysmon->masked_temp |=3D BIT(SYSMON_BIT_OT); + sysmon_region_event_handler(sysmon); + break; + + case SYSMON_BIT_ALARM4: + case SYSMON_BIT_ALARM3: + case SYSMON_BIT_ALARM2: + case SYSMON_BIT_ALARM1: + case SYSMON_BIT_ALARM0: + /* Read enabled alarms */ + sysmon_read_reg(sysmon, alarm_flag_offset, ®_val); + alarm_flag_reg =3D (unsigned long)reg_val; + + for_each_set_bit(bit, &alarm_flag_reg, 32) { + address =3D bit + (32 * event); + sysmon_push_event(indio_dev, address); + /* disable alarm */ + sysmon_update_reg(sysmon, alarm_reg_offset, BIT(bit), + 0); + } + /* clear alarms */ + sysmon_write_reg(sysmon, alarm_flag_offset, alarm_flag_reg); + break; + + default: + break; + } +} + +static void sysmon_handle_events(struct iio_dev *indio_dev, + unsigned long events) +{ + unsigned int bit; + + for_each_set_bit(bit, &events, SYSMON_NO_OF_EVENTS) + sysmon_handle_event(indio_dev, bit); +} + +static void sysmon_unmask_temp(struct sysmon *sysmon, unsigned int isr) +{ + unsigned int unmask, status; + + status =3D isr & SYSMON_TEMP_MASK; + + /* clear bits that are not active any more */ + unmask =3D (sysmon->masked_temp ^ status) & sysmon->masked_temp; + sysmon->masked_temp &=3D status; + + /* clear status of disabled alarm */ + unmask &=3D ~sysmon->temp_mask; + + sysmon_write_reg(sysmon, SYSMON_IER, unmask); +} + +/* + * The Versal threshold interrupts are level sensitive. Since we can't mak= e the + * threshold condition go way from within the interrupt handler, this mean= s as + * soon as a threshold condition is present we would enter the interrupt h= andler + * again and again. To work around this we mask all active thresholds inte= rrupts + * in the interrupt handler and start a timer. In this timer we poll the + * interrupt status and only if the interrupt is inactive we unmask it aga= in. + */ +static void sysmon_unmask_worker(struct work_struct *work) +{ + struct sysmon *sysmon =3D container_of(work, struct sysmon, + sysmon_unmask_work.work); + unsigned int isr; + + spin_lock_irq(&sysmon->lock); + + /* Read the current interrupt status */ + sysmon_read_reg(sysmon, SYSMON_ISR, &isr); + + /* Clear interrupts */ + sysmon_write_reg(sysmon, SYSMON_ISR, isr); + + sysmon_unmask_temp(sysmon, isr); + + spin_unlock_irq(&sysmon->lock); + + /* if still pending some alarm re-trigger the timer */ + if (sysmon->masked_temp) + schedule_delayed_work(&sysmon->sysmon_unmask_work, + msecs_to_jiffies(SYSMON_UNMASK_WORK_DELAY_MS)); + else + /* + * Reset the temp_max_max and temp_min_min values to reset the + * previously reached high/low values during an alarm. + * This will enable the user to see the high/low values attained + * during an event + */ + sysmon_write_reg(sysmon, SYSMON_STATUS_RESET, 1); +} + +static irqreturn_t sysmon_iio_irq(int irq, void *data) +{ + u32 isr, imr; + struct iio_dev *indio_dev =3D data; + struct sysmon *sysmon =3D iio_priv(indio_dev); + + spin_lock(&sysmon->lock); + + sysmon_read_reg(sysmon, SYSMON_ISR, &isr); + sysmon_read_reg(sysmon, SYSMON_IMR, &imr); + + /* only process alarm that are not masked */ + isr &=3D ~imr; + + /* clear interrupt */ + sysmon_write_reg(sysmon, SYSMON_ISR, isr); + + if (isr) { + sysmon_handle_events(indio_dev, isr); + + schedule_delayed_work(&sysmon->sysmon_unmask_work, + msecs_to_jiffies(SYSMON_UNMASK_WORK_DELAY_MS)); + } + + spin_unlock(&sysmon->lock); + + return IRQ_HANDLED; +} + +static void sysmon_events_worker(struct work_struct *work) +{ + u32 isr, imr; + struct sysmon *sysmon =3D container_of(work, struct sysmon, + sysmon_events_work.work); + + spin_lock(&sysmon->lock); + + sysmon_read_reg(sysmon, SYSMON_ISR, &isr); + sysmon_read_reg(sysmon, SYSMON_IMR, &imr); + + /* only process alarm that are not masked */ + isr &=3D ~imr; + + /* clear interrupt */ + sysmon_write_reg(sysmon, SYSMON_ISR, isr); + + if (isr) { + sysmon_handle_events(sysmon->indio_dev, isr); + schedule_delayed_work(&sysmon->sysmon_unmask_work, + msecs_to_jiffies(SYSMON_UNMASK_WORK_DELAY_MS)); + } + spin_unlock(&sysmon->lock); + + schedule_delayed_work(&sysmon->sysmon_events_work, + msecs_to_jiffies(SYSMON_EVENT_WORK_DELAY_MS)); +} + +static int get_hw_node_properties(struct device *dev, + struct list_head *region_list) +{ + struct region_info *region =3D NULL; + struct regional_node *nodes; + struct device_node *np =3D dev->of_node; + int size; + u32 id, satid, x, y, i, offset, prev =3D 0; + + /* get hw-node-info */ + if (!of_get_property(np, "hw-node", &size)) + return 0; + + if (size % 16) { + dev_info(dev, "HW-Node properties not correct"); + return -EINVAL; + } + + for (i =3D 0; i < (size / 16); i++) { + offset =3D i * 4; + of_property_read_u32_index(np, "hw-node", offset, &id); + of_property_read_u32_index(np, "hw-node", offset + 1, &satid); + of_property_read_u32_index(np, "hw-node", offset + 2, &x); + of_property_read_u32_index(np, "hw-node", offset + 3, &y); + + if (list_empty(region_list) || prev !=3D id) { + region =3D devm_kzalloc(dev, sizeof(*region), + GFP_KERNEL); + if (!region) + return -ENOMEM; + + region->id =3D (enum sysmon_region)id; + INIT_LIST_HEAD(®ion->node_list); + list_add(®ion->list, region_list); + } + + prev =3D id; + nodes =3D devm_kzalloc(dev, sizeof(*nodes), GFP_KERNEL); + if (!nodes) + return -ENOMEM; + nodes->sat_id =3D satid; + nodes->x =3D x; + nodes->y =3D y; + list_add(&nodes->regional_node_list, ®ion->node_list); + } + + return 0; +} + +int sysmon_parse_dt(struct iio_dev *indio_dev, struct device *dev) +{ + struct sysmon *sysmon; + struct iio_chan_spec *sysmon_channels; + struct device_node *child_node =3D NULL, *np =3D dev->of_node; + int ret, i =3D 0; + u32 num_supply_chan =3D 0; + u32 reg =3D 0, num_temp_chan =3D 0; + const char *name; + u32 chan_size =3D sizeof(struct iio_chan_spec); + u32 temp_chan_size; + + sysmon =3D iio_priv(indio_dev); + ret =3D of_property_read_u32(np, "xlnx,numchannels", &num_supply_chan); + if (ret < 0) + return ret; + + sysmon->num_supply_chan =3D num_supply_chan; + + INIT_LIST_HEAD(&sysmon->region_list); + + if (sysmon->irq > 0) + get_hw_node_properties(dev, &sysmon->region_list); + + /* Initialize buffer for channel specification */ + if (sysmon->master_slr) { + temp_chan_size =3D (sizeof(temp_channels) + sizeof(temp_events)); + num_temp_chan =3D ARRAY_SIZE(temp_channels); + } else if (sysmon->hbm_slr) { + temp_chan_size =3D (sizeof(temp_hbm_channels)); + num_temp_chan =3D ARRAY_SIZE(temp_hbm_channels); + } else { + temp_chan_size =3D sizeof(temp_events); + num_temp_chan =3D 0; + } + + sysmon_channels =3D devm_kzalloc(dev, (chan_size * num_supply_chan) + + temp_chan_size, + GFP_KERNEL); + if (!sysmon_channels) + return -ENOMEM; + + for_each_child_of_node(np, child_node) { + ret =3D of_property_read_u32(child_node, "reg", ®); + if (ret < 0) { + of_node_put(child_node); + return ret; + } + + ret =3D of_property_read_string(child_node, "xlnx,name", &name); + if (ret < 0) { + of_node_put(child_node); + return ret; + } + + sysmon_channels[i].type =3D IIO_VOLTAGE; + sysmon_channels[i].indexed =3D 1; + sysmon_channels[i].address =3D reg; + sysmon_channels[i].channel =3D reg; + sysmon_channels[i].info_mask_separate =3D + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED); + sysmon_channels[i].info_mask_shared_by_type =3D + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); + sysmon_channels[i].info_mask_shared_by_type_available =3D + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); + + sysmon_channels[i].event_spec =3D sysmon_supply_events; + sysmon_channels[i].num_event_specs =3D ARRAY_SIZE(sysmon_supply_events); + + sysmon_channels[i].scan_index =3D i; + sysmon_channels[i].scan_type.realbits =3D 19; + sysmon_channels[i].scan_type.storagebits =3D 32; + + sysmon_channels[i].scan_type.endianness =3D IIO_CPU; + sysmon_channels[i].extend_name =3D name; + + if (of_property_read_bool(child_node, "xlnx,bipolar")) + sysmon_channels[i].scan_type.sign =3D 's'; + else + sysmon_channels[i].scan_type.sign =3D 'u'; + + i++; + } + + /* Append static temperature channels to the channel list */ + indio_dev->num_channels =3D num_supply_chan; + + if (sysmon->master_slr) { + memcpy(sysmon_channels + num_supply_chan, temp_channels, + sizeof(temp_channels)); + indio_dev->num_channels +=3D ARRAY_SIZE(temp_channels); + } + + if (sysmon->hbm_slr) { + memcpy(sysmon_channels + num_supply_chan, temp_hbm_channels, + sizeof(temp_hbm_channels)); + indio_dev->num_channels +=3D num_temp_chan; + } else { + memcpy(sysmon_channels + num_supply_chan + num_temp_chan, + temp_events, sizeof(temp_events)); + indio_dev->num_channels +=3D ARRAY_SIZE(temp_events); + } + + indio_dev->channels =3D sysmon_channels; + + return 0; +} +EXPORT_SYMBOL(sysmon_parse_dt); + +int sysmon_init_interrupt(struct sysmon *sysmon) +{ + u32 imr; + int ret; + + INIT_DELAYED_WORK(&sysmon->sysmon_unmask_work, + sysmon_unmask_worker); + + sysmon_read_reg(sysmon, SYSMON_IMR, &imr); + sysmon->temp_mask =3D imr & SYSMON_TEMP_MASK; + + if (sysmon->irq > 0) { + g_sysmon =3D sysmon; + ret =3D devm_request_irq(sysmon->dev, sysmon->irq, &sysmon_iio_irq, + 0, "sysmon-irq", sysmon->indio_dev); + if (ret < 0) + return ret; + } else { + INIT_DELAYED_WORK(&sysmon->sysmon_events_work, + sysmon_events_worker); + schedule_delayed_work(&sysmon->sysmon_events_work, + msecs_to_jiffies(SYSMON_EVENT_WORK_DELAY_MS)); + } + + return 0; +} +EXPORT_SYMBOL(sysmon_init_interrupt); diff --git a/drivers/iio/adc/versal-sysmon.c b/drivers/iio/adc/versal-sysmo= n.c new file mode 100644 index 000000000000..79be5111b56c --- /dev/null +++ b/drivers/iio/adc/versal-sysmon.c @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD SYSMON for Versal + * + * Copyright (C) 2019 - 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc. + * + * Description: + * This driver is developed for SYSMON on Versal. The driver supports INDI= O Mode + * and supports voltage and temperature monitoring via IIO sysfs interface= and + * in kernel event monitoring for some modules. + */ + +#include +#include +#include +#include "versal-sysmon.h" + +static LIST_HEAD(sysmon_list_head); + +static struct iio_map sysmon_therm_static_maps[] =3D { + IIO_MAP("temp", "versal-thermal", "sysmon-temp-channel"), + {} +}; + +static inline int sysmon_direct_read_reg(struct sysmon *sysmon, u32 offset= , u32 *data) +{ + *data =3D readl(sysmon->base + offset); + + return 0; +} + +static inline void sysmon_direct_write_reg(struct sysmon *sysmon, u32 offs= et, u32 data) +{ + writel(data, sysmon->base + offset); +} + +static inline void sysmon_direct_update_reg(struct sysmon *sysmon, u32 off= set, + u32 mask, u32 data) +{ + u32 val; + + sysmon_direct_read_reg(sysmon, offset, &val); + sysmon_direct_write_reg(sysmon, offset, (val & ~mask) | (mask & data)); +} + +static struct sysmon_ops direct_access =3D { + .read_reg =3D sysmon_direct_read_reg, + .write_reg =3D sysmon_direct_write_reg, + .update_reg =3D sysmon_direct_update_reg, +}; + +/** + * sysmon_find_extreme_temp() - Finds extreme temperature + * value read from each device. + * @sysmon: Pointer to the sysmon instance + * @offset: Register offset address of temperature channels + * + * The function takes offset address of temperature channels + * returns extreme value (highest/lowest) of that channel + * + * @return: - The highest/lowest temperature found from + * current or historic min/max temperature of all devices. + */ +static int sysmon_find_extreme_temp(struct sysmon *sysmon, int offset) +{ + u32 extreme_val =3D SYSMON_LOWER_SATURATION_SIGNED; + bool is_min_channel =3D false, skip_hbm =3D true; + u32 regval; + + if (offset =3D=3D SYSMON_TEMP_MIN || offset =3D=3D SYSMON_TEMP_MIN_MIN) { + is_min_channel =3D true; + extreme_val =3D SYSMON_UPPER_SATURATION_SIGNED; + } else if (offset =3D=3D SYSMON_TEMP_HBM) { + skip_hbm =3D false; + } + + list_for_each_entry(sysmon, &sysmon_list_head, list) { + if (skip_hbm && sysmon->hbm_slr) + /* Skip if HBM SLR and need non HBM reading */ + continue; + + if (!skip_hbm && !sysmon->hbm_slr) + /* Skip if not HBM SLR and need a HBM reading */ + continue; + + sysmon_read_reg(sysmon, offset, ®val); + + if (sysmon->hbm_slr) + return regval; + + if (!is_min_channel) { + /* Find the highest value */ + if (compare(regval, extreme_val)) + extreme_val =3D regval; + } else { + /* Find the lowest value */ + if (compare(extreme_val, regval)) + extreme_val =3D regval; + } + } + + return extreme_val; +} + +static int sysmon_probe(struct platform_device *pdev) +{ + struct sysmon *sysmon, *temp_sysmon; + struct iio_dev *indio_dev; + struct resource *mem; + bool exist =3D false; + int ret; + + indio_dev =3D devm_iio_device_alloc(&pdev->dev, sizeof(*sysmon)); + if (!indio_dev) + return -ENOMEM; + + sysmon =3D iio_priv(indio_dev); + + sysmon->dev =3D &pdev->dev; + sysmon->indio_dev =3D indio_dev; + + mutex_init(&sysmon->mutex); + spin_lock_init(&sysmon->lock); + + indio_dev->dev.parent =3D &pdev->dev; + indio_dev->dev.of_node =3D pdev->dev.of_node; + indio_dev->name =3D "xlnx,versal-sysmon"; + sysmon_set_iio_dev_info(indio_dev); + indio_dev->modes =3D INDIO_DIRECT_MODE; + + sysmon->base =3D devm_platform_get_and_ioremap_resource(pdev, 0, &mem); + if (IS_ERR(sysmon->base)) + return PTR_ERR(sysmon->base); + + sysmon->ops =3D &direct_access; + + INIT_LIST_HEAD(&sysmon->list); + + mutex_lock(&sysmon->mutex); + + if (list_empty(&sysmon_list_head)) { + sysmon->master_slr =3D true; + } else { + list_for_each_entry(temp_sysmon, &sysmon_list_head, list) { + if (temp_sysmon->master_slr) + exist =3D true; + } + sysmon->master_slr =3D !exist; + } + + mutex_unlock(&sysmon->mutex); + + sysmon->hbm_slr =3D of_property_read_bool(pdev->dev.of_node, "xlnx,hbm"); + if (!sysmon->hbm_slr) { + sysmon_write_reg(sysmon, SYSMON_NPI_LOCK, NPI_UNLOCK); + sysmon_write_reg(sysmon, SYSMON_IDR, 0xffffffff); + sysmon_write_reg(sysmon, SYSMON_ISR, 0xffffffff); + sysmon->irq =3D platform_get_irq_optional(pdev, 0); + } + + ret =3D sysmon_parse_dt(indio_dev, &pdev->dev); + if (ret) + return ret; + + if (!sysmon->hbm_slr) { + ret =3D sysmon_init_interrupt(sysmon); + if (ret) + return ret; + } + + /* + * Sysmon dev info is cleared initially. + * temperature satellites and supply channels + * oversampling values will be 0. No need to + * assign them again. + */ + sysmon->oversampling_avail =3D sysmon_oversampling_avail; + sysmon->oversampling_num =3D ARRAY_SIZE(sysmon_oversampling_avail); + + sysmon->temp_read =3D &sysmon_find_extreme_temp; + + platform_set_drvdata(pdev, indio_dev); + + if (sysmon->master_slr) { + ret =3D devm_iio_map_array_register(&pdev->dev, indio_dev, + sysmon_therm_static_maps); + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, "IIO map register failed\n"); + } + + ret =3D iio_device_register(indio_dev); + if (ret < 0) + goto error_exit; + + /* Create the sysfs entries for the averaging enable bits */ + ret =3D sysmon_create_avg_en_sysfs_entries(indio_dev); + if (ret < 0) + goto error_exit; + + mutex_lock(&sysmon->mutex); + list_add(&sysmon->list, &sysmon_list_head); + mutex_unlock(&sysmon->mutex); + + return 0; + +error_exit: + if (sysmon->irq < 0) + cancel_delayed_work_sync(&sysmon->sysmon_events_work); + + cancel_delayed_work_sync(&sysmon->sysmon_unmask_work); + return ret; +} + +static void sysmon_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev =3D platform_get_drvdata(pdev); + struct sysmon *sysmon =3D iio_priv(indio_dev); + + /* cancel SSIT based events */ + if (sysmon->irq < 0) + cancel_delayed_work_sync(&sysmon->sysmon_events_work); + + cancel_delayed_work_sync(&sysmon->sysmon_unmask_work); + + mutex_lock(&sysmon->mutex); + list_del(&sysmon->list); + mutex_unlock(&sysmon->mutex); + + sysfs_remove_group(&indio_dev->dev.kobj, &sysmon->avg_attr_group); + /* Unregister the device */ + iio_device_unregister(indio_dev); +} + +static int sysmon_resume(struct platform_device *pdev) +{ + struct iio_dev *indio_dev =3D platform_get_drvdata(pdev); + struct sysmon *sysmon =3D iio_priv(indio_dev); + + sysmon_write_reg(sysmon, SYSMON_NPI_LOCK, NPI_UNLOCK); + + return 0; +} + +static const struct of_device_id sysmon_of_match_table[] =3D { + { .compatible =3D "xlnx,versal-sysmon" }, + {} +}; +MODULE_DEVICE_TABLE(of, sysmon_of_match_table); + +static struct platform_driver sysmon_driver =3D { + .probe =3D sysmon_probe, + .remove =3D sysmon_remove, + .resume =3D sysmon_resume, + .driver =3D { + .name =3D "sysmon", + .of_match_table =3D sysmon_of_match_table, + }, +}; +module_platform_driver(sysmon_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Xilinx Versal SysMon Driver"); +MODULE_AUTHOR("Advanced Micro Devices, Inc"); diff --git a/drivers/iio/adc/versal-sysmon.h b/drivers/iio/adc/versal-sysmo= n.h new file mode 100644 index 000000000000..ba47b6d32f4d --- /dev/null +++ b/drivers/iio/adc/versal-sysmon.h @@ -0,0 +1,275 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * AMD SYSMON for Versal + * + * Copyright (C) 2019 - 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc. + * + * Description: + * This driver is developed for SYSMON on Versal. The driver supports INDI= O Mode + * and supports voltage and temperature monitoring via IIO sysfs interface. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Channel IDs for Temp Channels */ +/* TEMP_MAX gives the current temperature for Production + * silicon. + * TEMP_MAX gives the current maximum temperature for ES1 + * silicon. + */ +#define TEMP_MAX 160 + +/* TEMP_MIN is not applicable for Production silicon. + * TEMP_MIN gives the current minimum temperature for ES1 silicon. + */ +#define TEMP_MIN 161 + +#define TEMP_MAX_MAX 162 +#define TEMP_MIN_MIN 163 +#define TEMP_EVENT 164 +#define OT_EVENT 165 +#define TEMP_HBM 166 + +/* Register Unlock Code */ +#define NPI_UNLOCK 0xF9E8D7C6 + +/* Register Offsets */ +#define SYSMON_NPI_LOCK 0x000C +#define SYSMON_ISR 0x0044 +#define SYSMON_CONFIG 0x0100 +#define SYSMON_TEMP_MASK 0x300 +#define SYSMON_IMR 0x0048 +#define SYSMON_IER 0x004C +#define SYSMON_IDR 0x0050 +#define SYSMON_ALARM_FLAG 0x1018 +#define SYSMON_TEMP_MAX 0x1030 +#define SYSMON_TEMP_MIN 0x1034 +#define SYSMON_SUPPLY_BASE 0x1040 +#define SYSMON_ALARM_REG 0x1940 +#define SYSMON_TEMP_TH_LOW 0x1970 +#define SYSMON_TEMP_TH_UP 0x1974 +#define SYSMON_OT_TH_LOW 0x1978 +#define SYSMON_OT_TH_UP 0x197C +#define SYSMON_SUPPLY_TH_LOW 0x1980 +#define SYSMON_SUPPLY_TH_UP 0x1C80 +#define SYSMON_TEMP_MAX_MAX 0x1F90 +#define SYSMON_TEMP_MIN_MIN 0x1F8C +#define SYSMON_TEMP_HBM 0x0000 +#define SYSMON_TEMP_EV_CFG 0x1F84 +#define SYSMON_NODE_OFFSET 0x1FAC +#define SYSMON_STATUS_RESET 0x1F94 +#define SYSMON_SUPPLY_EN_AVG_OFFSET 0x1958 +#define SYSMON_TEMP_SAT_EN_AVG_OFFSET 0x24B4 + +/* Average Sampling Rate macros */ +#define SYSMON_AVERAGE_FULL_SAMPLE_RATE 0 /* Full sample rate */ +#define SYSMON_AVERAGE_2_SAMPLE_RATE 1 /* Full sample rate/2 */ +#define SYSMON_AVERAGE_4_SAMPLE_RATE 2 /* Full sample rate/4 */ +#define SYSMON_AVERAGE_8_SAMPLE_RATE 4 /* Full sample rate/8 */ +#define SYSMON_AVERAGE_16_SAMPLE_RATE 8 /* Full sample rate/16 */ + +#define SYSMON_TEMP_SAT_IDX_FIRST 1 +#define SYSMON_TEMP_SAT_IDX_MAX 64 +#define SYSMON_TEMP_SAT_COUNT 64 +#define SYSMON_SUPPLY_IDX_MAX 159 + +#define SYSMON_SUPPLY_CONFIG_MASK GENMASK(17, 14) +#define SYSMON_SUPPLY_CONFIG_SHIFT 14 +#define SYSMON_TEMP_SAT_CONFIG_MASK GENMASK(27, 24) +#define SYSMON_TEMP_SAT_CONFIG_SHIFT 24 + +#define SYSMON_NO_OF_EVENTS 32 + +/* Supply Voltage Conversion macros */ +#define SYSMON_MANTISSA_MASK 0xFFFF +#define SYSMON_FMT_MASK 0x10000 +#define SYSMON_FMT_SHIFT 16 +#define SYSMON_MODE_MASK 0x60000 +#define SYSMON_MODE_SHIFT 17 +#define SYSMON_MANTISSA_SIGN_SHIFT 15 +#define SYSMON_UPPER_SATURATION_SIGNED 32767 +#define SYSMON_LOWER_SATURATION_SIGNED -32768 +#define SYSMON_UPPER_SATURATION 65535 +#define SYSMON_LOWER_SATURATION 0 + +#define SYSMON_MILLI_SCALE 1000 + +#define SYSMON_CHAN_TEMP_EVENT(_address, _ext, _events) { \ + .type =3D IIO_TEMP, \ + .indexed =3D 1, \ + .address =3D _address, \ + .channel =3D _address, \ + .event_spec =3D _events, \ + .num_event_specs =3D ARRAY_SIZE(_events), \ + .scan_type =3D { \ + .sign =3D 's', \ + .realbits =3D 15, \ + .storagebits =3D 16, \ + .endianness =3D IIO_CPU, \ + }, \ + .extend_name =3D _ext, \ + } + +#define SYSMON_CHAN_TEMP(_address, _ext) { \ + .type =3D IIO_TEMP, \ + .indexed =3D 1, \ + .address =3D _address, \ + .channel =3D _address, \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_PROCESSED), \ + .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_shared_by_type_available =3D \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .scan_type =3D { \ + .sign =3D 's', \ + .realbits =3D 15, \ + .storagebits =3D 16, \ + .endianness =3D IIO_CPU, \ + }, \ + .extend_name =3D _ext, \ + .datasheet_name =3D _ext,\ +} + +#define SYSMON_CHAN_TEMP_HBM(_address, _ext) { \ + .type =3D IIO_TEMP, \ + .indexed =3D 1, \ + .address =3D _address, \ + .channel =3D _address, \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_PROCESSED), \ + .scan_type =3D { \ + .sign =3D 's', \ + .realbits =3D 15, \ + .storagebits =3D 16, \ + .endianness =3D IIO_CPU, \ + }, \ + .extend_name =3D _ext, \ + .datasheet_name =3D _ext, \ +} + +#define twoscomp(val) ((((val) ^ 0xFFFF) + 1) & 0x0000FFFF) +#define REG32_OFFSET(address) (4 * ((address) / 32)) +#define REG32_SHIFT(address) ((address) % 32) + +#define compare(val, thresh) (((val) & 0x8000) || ((thresh) & 0x8000) ? \ + ((val) < (thresh)) : ((val) > (thresh))) \ + +enum sysmon_alarm_bit { + SYSMON_BIT_ALARM0 =3D 0, + SYSMON_BIT_ALARM1 =3D 1, + SYSMON_BIT_ALARM2 =3D 2, + SYSMON_BIT_ALARM3 =3D 3, + SYSMON_BIT_ALARM4 =3D 4, + SYSMON_BIT_ALARM5 =3D 5, + SYSMON_BIT_ALARM6 =3D 6, + SYSMON_BIT_ALARM7 =3D 7, + SYSMON_BIT_OT =3D 8, + SYSMON_BIT_TEMP =3D 9, +}; + +static const unsigned int sysmon_oversampling_avail[5] =3D { + SYSMON_AVERAGE_FULL_SAMPLE_RATE, + SYSMON_AVERAGE_2_SAMPLE_RATE, + SYSMON_AVERAGE_4_SAMPLE_RATE, + SYSMON_AVERAGE_8_SAMPLE_RATE, + SYSMON_AVERAGE_16_SAMPLE_RATE, +}; + +/** + * struct sysmon - Driver data for Sysmon + * @base: physical base address of device + * @dev: pointer to device struct + * @indio_dev: pointer to the iio device + * @client: pointer to the i2c client + * @mutex: to handle multiple user interaction + * @lock: to help manage interrupt registers correctly + * @irq: interrupt number of the sysmon + * @region_list: list of the regions of sysmon + * @list: list of sysmon instances + * @masked_temp: currently masked due to alarm + * @temp_mask: temperature based interrupt configuration + * @sysmon_unmask_work: re-enables event once the event condition disappea= rs + * @sysmon_events_work: poll for events on SSIT slices + * @ops: read write operations for sysmon registers + * @pm_info: plm address of sysmon + * @master_slr: to keep master sysmon info + * @hbm_slr: flag if HBM slr is present + * @temp_oversampling: current oversampling ratio for temperature satellit= es + * @supply_oversampling: current oversampling ratio for supply nodes + * @oversampling_avail: list of available overampling ratios + * @oversampling_num: total number of available oversampling ratios + * @num_supply_chan: number of supply channels that are enabled + * @supply_avg_en_attrs: dynamic array of supply averaging enable attribut= es + * @temp_avg_en_attrs: dynamic array of temp. sat. averaging enable attrib= utes + * @avg_attrs: dynamic array of pointers to averaging attributes + * @avg_attr_group: attribute group for averaging + * @temp_read: function pointer for the special temperature read + * + * This structure contains necessary state for Sysmon driver to operate + */ +struct sysmon { + void __iomem *base; + struct device *dev; + struct iio_dev *indio_dev; + struct i2c_client *client; + /* kernel doc above */ + struct mutex mutex; + /* kernel doc above */ + spinlock_t lock; + int irq; + struct list_head region_list; + struct list_head list; + unsigned int masked_temp; + unsigned int temp_mask; + struct delayed_work sysmon_unmask_work; + struct delayed_work sysmon_events_work; + struct sysmon_ops *ops; + u32 pm_info; + bool master_slr; + bool hbm_slr; + unsigned int temp_oversampling; + unsigned int supply_oversampling; + const unsigned int *oversampling_avail; + unsigned int oversampling_num; + unsigned int num_supply_chan; + struct iio_dev_attr *supply_avg_en_attrs; + struct iio_dev_attr *temp_avg_en_attrs; + struct attribute **avg_attrs; + struct attribute_group avg_attr_group; + int (*temp_read)(struct sysmon *sysmon, int offset); +}; + +struct sysmon_ops { + int (*read_reg)(struct sysmon *sysmon, u32 offset, u32 *data); + void (*write_reg)(struct sysmon *sysmon, u32 offset, u32 data); + void (*update_reg)(struct sysmon *sysmon, u32 offset, + u32 mask, u32 data); +}; + +int sysmon_register_temp_ops(void (*cb)(void *data, struct regional_node *= node), + void *data, enum sysmon_region region_id); +int sysmon_unregister_temp_ops(enum sysmon_region region_id); +struct list_head *sysmon_nodes_by_region(enum sysmon_region region_id); +int sysmon_get_node_value(int sat_id); +int sysmon_parse_dt(struct iio_dev *indio_dev, struct device *dev); +int sysmon_init_interrupt(struct sysmon *sysmon); +int sysmon_read_reg(struct sysmon *sysmon, u32 offset, u32 *data); +void sysmon_write_reg(struct sysmon *sysmon, u32 offset, u32 data); +void sysmon_set_iio_dev_info(struct iio_dev *indio_dev); +int sysmon_create_avg_en_sysfs_entries(struct iio_dev *indio_dev); diff --git a/include/linux/iio/adc/versal-sysmon-events.h b/include/linux/i= io/adc/versal-sysmon-events.h new file mode 100644 index 000000000000..d0a8b3e959c4 --- /dev/null +++ b/include/linux/iio/adc/versal-sysmon-events.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Xilinx SYSMON hardware info + * + * Copyright (C) 2019 - 2022, Xilinx, Inc. + * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc. + * + */ +#ifndef _VERSAL_SYSMON_EVENTS_H_ +#define _VERSAL_SYSMON_EVENTS_H_ + +#include +#include + +/* Sysmon region ids */ +enum sysmon_region { + SYSMON_AIE =3D 0, + SYSMON_PMC =3D 1, + SYSMON_XPIO =3D 2, + SYSMON_VNOC =3D 3, + SYSMON_CC =3D 4, +}; + +/** + * struct regional_node - regional node properties + * @sat_id: node_id + * @x: x co-ordinate of the node + * @y: y co-ordinate of the node + * @temp: raw sensor value + * @regional_node_list: list of nodes in the region + */ +struct regional_node { + int sat_id; + int x; + int y; + u16 temp; + struct list_head regional_node_list; +}; + +/** + * struct region_info - information about a regions sensors + * @id: region id + * @cb: callback to be called when there is a region specific event + * @data: pointer to the callback data + * @node_list: head to the regional_nodes list + * @list: list of regions + */ +struct region_info { + enum sysmon_region id; + void (*cb)(void *data, struct regional_node *node); + void *data; + struct list_head node_list; + struct list_head list; +}; + +#endif --=20 2.43.0 From nobody Tue Sep 9 21:28:52 2025 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2052.outbound.protection.outlook.com [40.107.244.52]) (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 E3FCC280A29; Fri, 5 Sep 2025 08:42:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.244.52 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061750; cv=fail; b=nyzPMoodexdmFLUsWgaes16lX0qLmuIO/rgcR9D1R94faBXgWI1U5QpjYfcCOw+wgjmg74utHLy7DZpNy0zQfZea9M1p2hxtOeLYzAEEPwvHh/1KOuNBLgALya7kD91LxorSy+rtc0X6vzjJOTQqegmsbc0k378hcTfrVSx139s= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061750; c=relaxed/simple; bh=Y5m3Jh1C2iQcvCumDKeHuR7glY4zl5oen+77YKJdhA8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=TZqASpa+AcFdyz4hHPb9B2lsx4vbeLkl/dip41IcnO5VrmlVuzoY54gGL4ttmdA234FqH45ZbjQ7Ss2yQFxDvRb/dSAMFkGr6nPO2LB2imj+aEWbj3GTklhi+Ck18lWdpsHDMkE9jf09jNvRQK4ibN2gYz+rXGGgud6+3rJeNhI= 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=uEAS9OUo; arc=fail smtp.client-ip=40.107.244.52 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="uEAS9OUo" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=kZ/Dgwf0FwXA4gINHtKdkc8BQBDusWyRQyW/NL2O+Oy0deAlW1qjaTKXSJ8XCzCVkB4VKncCJiZGgNkmQv3YFL0wGR38WwRJKdSDJyMUiPiSKM3KYbhKy9hGdgeoqXBvfK/xY9aGk/zCl4MCnrJH9UhjbcCiQIEprnyPxXUSk/Li82bcQCZfsKGrRwyp3CpQ4gcyx4H+cil9g23OaIY331kXHw9yc+rRcziCeA3osbu/yqThyogujB+I6E+rCbV6B+pvQZPqVpHnVhXEaeXqGP1025EzaOU0iSzoeax8yKpG0hzx04OavvkVz+radgxeadzpfEodlPr52/ajet0zXg== 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=9JcQbUkDQrLwz13FKDmf3QcTe59Oi4e7Uymi7sjqSnA=; b=SJps2/YB6UqLGKo++1wfsLxqG9UseOxxD2Yp0ZA7Ta/7w2DcW9aDiQlpKS3/lCCHOY9Ae4q5lw8DP54mzaRfNB5BJI8zlGjGks0tPq6ASEhQ8zLt/mwsQNm0giA6y3ItKNkAwMzXV88aPq4+i7TYyQf/rg5KWsdua2rG79MOgzv7c4fe6nle9Wy0tSNqFSmVRAVLaQzaQRdxSlGCH1QoQWuf9n789vDMqnAf3QFiMaogF0zcqD3fA+cRRK/sx7PJSsGF7lTF2GSvqktJ51BojaNcFNCDsi+eTdgd5DxBLSqvqXlcZzINMFYgSqzrhAIXzQ1c7+H6HvbBrCICA6ikPw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.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=9JcQbUkDQrLwz13FKDmf3QcTe59Oi4e7Uymi7sjqSnA=; b=uEAS9OUojGpIxoinA4CeD79h3DCglB6Yv5bCXfttKMuouwGjdw3/Hw7meoLNbAcc1b3GZ4QNBja0YnHUf7rmee3vJKG2GXtrvUP+hRfrOkFnJWM9Kqed5imN62i1f9q+EVvJoQq/MzxXFRcZUQesxXWwGEfhUszv/YNQ9rTBOjM= Received: from BYAPR01CA0043.prod.exchangelabs.com (2603:10b6:a03:94::20) by DM4PR12MB7718.namprd12.prod.outlook.com (2603:10b6:8:102::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9094.16; Fri, 5 Sep 2025 08:42:23 +0000 Received: from SJ5PEPF000001EC.namprd05.prod.outlook.com (2603:10b6:a03:94:cafe::2f) by BYAPR01CA0043.outlook.office365.com (2603:10b6:a03:94::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9094.17 via Frontend Transport; Fri, 5 Sep 2025 08:42: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 SJ5PEPF000001EC.mail.protection.outlook.com (10.167.242.200) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9094.14 via Frontend Transport; Fri, 5 Sep 2025 08:42:23 +0000 Received: from SATLEXMB04.amd.com (10.181.40.145) 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; Fri, 5 Sep 2025 03:42:08 -0500 Received: from localhost (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 via Frontend Transport; Fri, 5 Sep 2025 03:42:08 -0500 From: Michal Simek To: , , , CC: Anish Kadamathikuttiyil Karthikeyan Pillai , Andy Shevchenko , David Lechner , Jonathan Cameron , =?UTF-8?q?Nuno=20S=C3=A1?= , "Salih Erim" , "open list:IIO SUBSYSTEM AND DRIVERS" Subject: [PATCH 3/6] iio: adc: versal-sysmon: Support AI Engine thermal monitoring Date: Fri, 5 Sep 2025 10:41:46 +0200 Message-ID: <2db88a5373dd410af6c55210032ed81ceae16323.1757061697.git.michal.simek@amd.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=11086; i=michal.simek@amd.com; h=from:subject:message-id; bh=kVSj/ygXyjOmToPGLBmSJYQTdFYjy8ufby4mRVDowLo=; b=owGbwMvMwCG2mv3fB7+vgl8ZT6slMWTsWuTnOIU/q+fmvdd6P0tt5i5n+XGMY29MbNO9R5mCH dKO5plhHaUsDGIcDLJiiizTmXQc1ny7tlRseWQ+zBxWJpAhDFycAjCRpmeMDMv55d5dFG4oyZPZ eyOf+/K5F/v+hatuXjlPlU1aZdHylheMDIttdp+y0iuNFFuStnd106IdN/1/Hj748OADO0HrB4K F2jwA X-Developer-Key: i=michal.simek@amd.com; a=openpgp; fpr=67350C9BF5CCEE9B5364356A377C7F21FE3D1F91 Content-Transfer-Encoding: quoted-printable Received-SPF: None (SATLEXMB04.amd.com: michal.simek@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EC:EE_|DM4PR12MB7718:EE_ X-MS-Office365-Filtering-Correlation-Id: ae246e5f-9eb1-45b5-fdb5-08ddec582277 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|1800799024|82310400026|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?Xf/gL2oXyq1loey3v0sDGaP4P9jUh6xE9LjiccWgiSQmBxY0Ap9lCPFhn0Es?= =?us-ascii?Q?iYTX+cJWo9yyNZ3tUCi5dJC56yEoWXEUpaujdqTO7ihA6WWEqXZeR5jNByf7?= =?us-ascii?Q?es0jcHR9vJhTdkMB5stbhE/OdyZlR8h9+KrFAttNu7kfSYt68lzDHH8fd7xx?= =?us-ascii?Q?9Uy6cT6Cmrle2ltmjEK6UgNHDnoUmRJb6VQ7395uedwBrFXdmFEO5jakjPyK?= =?us-ascii?Q?TGMF+rmkiPWvOxkcFfRrh5cx/7Esh3SkGgStE5sVoJwlzWum7XMpWwurPQ+B?= =?us-ascii?Q?TVZCJP8fhL9MM0/niSeLWYy5Gy0Lkpry2vefGuUaA3tpj0vGPwXKxdH5hlKn?= =?us-ascii?Q?TTz0/Me4GiYULbEs9Kv4EheZnvHMOtO55LnhgnKu0OU2aAZPC1jwxkc5Lnm3?= =?us-ascii?Q?Wpc2gh+748LMPUSPhj0YXLFVCEpNCzNnY/hC9tb7UvI+wK9WmPjdRz0Tp6xs?= =?us-ascii?Q?XK0MrZS1oVAwKsHWkjrxhxQBYBkalqcFnp5LMpjvbnHExBZPFXImvWHTWGVE?= =?us-ascii?Q?fr1KYhg3TT277gnAa2tccQ5YRDlE3lAZ3ASF4V2yXqOktu7dmeEB0lLtzlqe?= =?us-ascii?Q?5duyymYEuB83eGMu9IvHWbjxOxj/TSlsRYFlQlrdM1Luie04yyezfzujqK+o?= =?us-ascii?Q?alt3ahF6cL3UNezBacfeDxZF81XDD72DqAKVbPiOPsyPFkZfSeVKe+Wo+s11?= =?us-ascii?Q?PDOaYfeaV+Y40n23jNpNMescrC6VbYkrtzpJeUo0/KmndT4saOtNO4F7xDzj?= =?us-ascii?Q?xvN9Tx2Wc8KVgxF1Nq6sLEbGjoHdw+0EF4VIGND72LWEtAeKVP89UtB4N66N?= =?us-ascii?Q?P3Xs5X9N+TYwqRmg3wvaBJqZPY5h4cJOuSXqwraM6bkex9BTCzQGszx8wnZT?= =?us-ascii?Q?qbBh4zrVLhPP9x4uGHgAL3G+UW7Q5FsOfIxuFns9bHb9UX23ExzK+7UUKhSH?= =?us-ascii?Q?RSqw4RFcw5eOq5VwMOibzERjtPl+LBV66bByXYEwS8LEowC6TOW5L0URX41R?= =?us-ascii?Q?cOAEMyoqfnwu954IzlDjXV19sj7A3Yq5v2eSDfEhd2A2mAVBRaujmVZp+joY?= =?us-ascii?Q?i2MdSm6RX9M45kIx5jt7k0fNR4yYF1yHNzQBD4v02Z5Qsegmwnf4aJPlLNNU?= =?us-ascii?Q?W1qZnPajWCryQ69Eu0bkJRKzJdIvHNFEcT71D6HR/AwZiy68YozQ7cWmduR0?= =?us-ascii?Q?/CIX2e6IdB9CoSF9dcQXDnhBE0KuQ74aurfR+G7nCw7Q5fPwAGo4hm9zKdSb?= =?us-ascii?Q?6j6wvCWYraVv2+msSgA8RWKtDOOZg3ACxeJOOY/zBLWKF8El6PLBt1PHkC/7?= =?us-ascii?Q?RbNVYdZxHeY8il/qM5tmh8qy8ww/UTD0R2yN3ebWlXdJcmlxVN1hNHp2pIbl?= =?us-ascii?Q?6mThZo04TDLpcxwto1cyhiFu/kT8rBw5UrzW3KhWAJspQXj0Z42tVgUF7Z+u?= =?us-ascii?Q?jgBRvHW+X+XRh3s5FK4QH0K9Y0pkiWwc3TE+rtSkOxP7DFjt+xgVe272ZsD8?= =?us-ascii?Q?z8KkYx506fG1nvggEoK8dBMqY5jW6OsiGpYZ?= 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)(36860700013)(1800799024)(82310400026)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2025 08:42:23.4707 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ae246e5f-9eb1-45b5-fdb5-08ddec582277 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: SJ5PEPF000001EC.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB7718 Content-Type: text/plain; charset="utf-8" From: Anish Kadamathikuttiyil Karthikeyan Pillai To enhance the thermal monitoring of AI Engine, the sysmon satellites close to it are exposed as IIO channels. The exposed IIO channel are mapped to allow consumer drivers to access specific sensor data through the IIO framework. Signed-off-by: Anish Kadamathikuttiyil Karthikeyan Pillai Signed-off-by: Michal Simek --- drivers/iio/adc/versal-sysmon-core.c | 135 ++++++++++++++++++--------- drivers/iio/adc/versal-sysmon.c | 35 ++++++- drivers/iio/adc/versal-sysmon.h | 3 + 3 files changed, 127 insertions(+), 46 deletions(-) diff --git a/drivers/iio/adc/versal-sysmon-core.c b/drivers/iio/adc/versal-= sysmon-core.c index 21b6a413dccb..bd293ff7d176 100644 --- a/drivers/iio/adc/versal-sysmon-core.c +++ b/drivers/iio/adc/versal-sysmon-core.c @@ -272,7 +272,10 @@ static int sysmon_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_TEMP: - offset =3D sysmon_temp_offset(chan->address); + if (chan->channel !=3D AIE_TEMP_CH) + offset =3D sysmon_temp_offset(chan->address); + else + offset =3D chan->address; *val =3D sysmon->temp_read(sysmon, offset); *val2 =3D 0; ret =3D IIO_VAL_INT; @@ -295,7 +298,10 @@ static int sysmon_read_raw(struct iio_dev *indio_dev, switch (chan->type) { case IIO_TEMP: /* In Deg C */ - offset =3D sysmon_temp_offset(chan->address); + if (chan->channel !=3D AIE_TEMP_CH) + offset =3D sysmon_temp_offset(chan->address); + else + offset =3D chan->address; regval =3D sysmon->temp_read(sysmon, offset); if (!sysmon->hbm_slr) sysmon_q8p7_to_millicelsius(regval, val, val2); @@ -1202,8 +1208,10 @@ int sysmon_parse_dt(struct iio_dev *indio_dev, struc= t device *dev) struct iio_chan_spec *sysmon_channels; struct device_node *child_node =3D NULL, *np =3D dev->of_node; int ret, i =3D 0; + int aie_idx =3D 0; u32 num_supply_chan =3D 0; u32 reg =3D 0, num_temp_chan =3D 0; + u32 num_aie_temp_chan =3D 0; const char *name; u32 chan_size =3D sizeof(struct iio_chan_spec); u32 temp_chan_size; @@ -1214,6 +1222,11 @@ int sysmon_parse_dt(struct iio_dev *indio_dev, struc= t device *dev) return ret; =20 sysmon->num_supply_chan =3D num_supply_chan; + ret =3D of_property_read_u32(np, "xlnx,numaiechannels", &num_aie_temp_cha= n); + if (ret < 0) + num_aie_temp_chan =3D 0; + + sysmon->num_aie_temp_chan =3D num_aie_temp_chan; =20 INIT_LIST_HEAD(&sysmon->region_list); =20 @@ -1233,69 +1246,101 @@ int sysmon_parse_dt(struct iio_dev *indio_dev, str= uct device *dev) } =20 sysmon_channels =3D devm_kzalloc(dev, (chan_size * num_supply_chan) + + (chan_size * num_aie_temp_chan) + temp_chan_size, GFP_KERNEL); if (!sysmon_channels) return -ENOMEM; =20 + /* Configure the dynamic channels */ for_each_child_of_node(np, child_node) { - ret =3D of_property_read_u32(child_node, "reg", ®); - if (ret < 0) { - of_node_put(child_node); - return ret; - } + if (of_property_present(child_node, "xlnx,aie-temp")) { + ret =3D of_property_read_u32(child_node, "reg", ®); + if (ret < 0) { + of_node_put(child_node); + return ret; + } + ret =3D of_property_read_string(child_node, "xlnx,name", &name); + if (ret < 0) { + of_node_put(child_node); + return ret; + } + sysmon_channels[num_supply_chan + aie_idx].type =3D IIO_TEMP; + sysmon_channels[num_supply_chan + aie_idx].indexed =3D 1; + sysmon_channels[num_supply_chan + aie_idx].address =3D + SYSMON_NODE_OFFSET + ((reg - 1) * 4); + sysmon_channels[num_supply_chan + aie_idx].channel =3D AIE_TEMP_CH; + sysmon_channels[num_supply_chan + aie_idx].info_mask_separate =3D + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED); + sysmon_channels[num_supply_chan + aie_idx].scan_index =3D aie_idx; + sysmon_channels[num_supply_chan + aie_idx].scan_type.realbits =3D 15; + sysmon_channels[num_supply_chan + aie_idx].scan_type.storagebits =3D + 16; + sysmon_channels[num_supply_chan + aie_idx].scan_type.endianness =3D + IIO_CPU; + sysmon_channels[num_supply_chan + aie_idx].scan_type.sign =3D 's'; + sysmon_channels[num_supply_chan + aie_idx].extend_name =3D name; + sysmon_channels[num_supply_chan + aie_idx].datasheet_name =3D name; + aie_idx++; + } else { + ret =3D of_property_read_u32(child_node, "reg", ®); + if (ret < 0) { + of_node_put(child_node); + return ret; + } =20 - ret =3D of_property_read_string(child_node, "xlnx,name", &name); - if (ret < 0) { - of_node_put(child_node); - return ret; - } + ret =3D of_property_read_string(child_node, "xlnx,name", &name); + if (ret < 0) { + of_node_put(child_node); + return ret; + } =20 - sysmon_channels[i].type =3D IIO_VOLTAGE; - sysmon_channels[i].indexed =3D 1; - sysmon_channels[i].address =3D reg; - sysmon_channels[i].channel =3D reg; - sysmon_channels[i].info_mask_separate =3D - BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED); - sysmon_channels[i].info_mask_shared_by_type =3D - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); - sysmon_channels[i].info_mask_shared_by_type_available =3D - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); - - sysmon_channels[i].event_spec =3D sysmon_supply_events; - sysmon_channels[i].num_event_specs =3D ARRAY_SIZE(sysmon_supply_events); - - sysmon_channels[i].scan_index =3D i; - sysmon_channels[i].scan_type.realbits =3D 19; - sysmon_channels[i].scan_type.storagebits =3D 32; - - sysmon_channels[i].scan_type.endianness =3D IIO_CPU; - sysmon_channels[i].extend_name =3D name; - - if (of_property_read_bool(child_node, "xlnx,bipolar")) - sysmon_channels[i].scan_type.sign =3D 's'; - else - sysmon_channels[i].scan_type.sign =3D 'u'; + sysmon_channels[i].type =3D IIO_VOLTAGE; + sysmon_channels[i].indexed =3D 1; + sysmon_channels[i].address =3D reg; + sysmon_channels[i].channel =3D reg; + sysmon_channels[i].info_mask_separate =3D + BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED); + sysmon_channels[i].info_mask_shared_by_type =3D + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); + sysmon_channels[i].info_mask_shared_by_type_available =3D + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); + + sysmon_channels[i].event_spec =3D sysmon_supply_events; + sysmon_channels[i].num_event_specs =3D ARRAY_SIZE(sysmon_supply_events); + + sysmon_channels[i].scan_index =3D i; + sysmon_channels[i].scan_type.realbits =3D 19; + sysmon_channels[i].scan_type.storagebits =3D 32; + + sysmon_channels[i].scan_type.endianness =3D IIO_CPU; + sysmon_channels[i].extend_name =3D name; + + if (of_property_read_bool(child_node, "xlnx,bipolar")) + sysmon_channels[i].scan_type.sign =3D 's'; + else + sysmon_channels[i].scan_type.sign =3D 'u'; =20 - i++; + i++; + } } =20 /* Append static temperature channels to the channel list */ - indio_dev->num_channels =3D num_supply_chan; + indio_dev->num_channels =3D num_supply_chan + num_aie_temp_chan; =20 if (sysmon->master_slr) { - memcpy(sysmon_channels + num_supply_chan, temp_channels, - sizeof(temp_channels)); + memcpy(sysmon_channels + num_supply_chan + num_aie_temp_chan, + temp_channels, sizeof(temp_channels)); indio_dev->num_channels +=3D ARRAY_SIZE(temp_channels); } =20 if (sysmon->hbm_slr) { - memcpy(sysmon_channels + num_supply_chan, temp_hbm_channels, - sizeof(temp_hbm_channels)); + memcpy(sysmon_channels + num_supply_chan + num_aie_temp_chan, + temp_hbm_channels, sizeof(temp_hbm_channels)); indio_dev->num_channels +=3D num_temp_chan; } else { - memcpy(sysmon_channels + num_supply_chan + num_temp_chan, - temp_events, sizeof(temp_events)); + memcpy(sysmon_channels + num_supply_chan + num_aie_temp_chan + + num_temp_chan, temp_events, sizeof(temp_events)); indio_dev->num_channels +=3D ARRAY_SIZE(temp_events); } =20 diff --git a/drivers/iio/adc/versal-sysmon.c b/drivers/iio/adc/versal-sysmo= n.c index 79be5111b56c..b839dfdef712 100644 --- a/drivers/iio/adc/versal-sysmon.c +++ b/drivers/iio/adc/versal-sysmon.c @@ -108,8 +108,13 @@ static int sysmon_probe(struct platform_device *pdev) struct sysmon *sysmon, *temp_sysmon; struct iio_dev *indio_dev; struct resource *mem; + struct iio_map *all_maps; + const struct iio_chan_spec *chan; bool exist =3D false; int ret; + int maps_size =3D 0; + int maps_idx =3D 0; + int dyn_idx =3D 0; =20 indio_dev =3D devm_iio_device_alloc(&pdev->dev, sizeof(*sysmon)); if (!indio_dev) @@ -183,8 +188,36 @@ static int sysmon_probe(struct platform_device *pdev) platform_set_drvdata(pdev, indio_dev); =20 if (sysmon->master_slr) { + /* Combine static and dynamic iio maps and register */ + maps_size =3D ARRAY_SIZE(sysmon_therm_static_maps) - 1 + + sysmon->num_aie_temp_chan; + all_maps =3D devm_kzalloc(&pdev->dev, + sizeof(*all_maps) * (maps_size), GFP_KERNEL); + if (!all_maps) + return -ENOMEM; + + for (maps_idx =3D 0; + maps_idx < ARRAY_SIZE(sysmon_therm_static_maps) - 1; + maps_idx++) + all_maps[maps_idx] =3D + sysmon_therm_static_maps[maps_idx]; + + for (dyn_idx =3D 0; dyn_idx < indio_dev->num_channels && maps_idx < maps= _size; + dyn_idx++) { + chan =3D &indio_dev->channels[dyn_idx]; + + if (chan->channel =3D=3D AIE_TEMP_CH) { + all_maps[maps_idx].adc_channel_label =3D + chan->extend_name; + all_maps[maps_idx].consumer_dev_name =3D + "versal-thermal"; + all_maps[maps_idx].consumer_channel =3D + chan->extend_name; + maps_idx++; + } + } ret =3D devm_iio_map_array_register(&pdev->dev, indio_dev, - sysmon_therm_static_maps); + all_maps); if (ret < 0) return dev_err_probe(&pdev->dev, ret, "IIO map register failed\n"); } diff --git a/drivers/iio/adc/versal-sysmon.h b/drivers/iio/adc/versal-sysmo= n.h index ba47b6d32f4d..f49a4e60de65 100644 --- a/drivers/iio/adc/versal-sysmon.h +++ b/drivers/iio/adc/versal-sysmon.h @@ -45,6 +45,7 @@ #define TEMP_EVENT 164 #define OT_EVENT 165 #define TEMP_HBM 166 +#define AIE_TEMP_CH 200 =20 /* Register Unlock Code */ #define NPI_UNLOCK 0xF9E8D7C6 @@ -215,6 +216,7 @@ static const unsigned int sysmon_oversampling_avail[5] = =3D { * @oversampling_avail: list of available overampling ratios * @oversampling_num: total number of available oversampling ratios * @num_supply_chan: number of supply channels that are enabled + * @num_aie_temp_chan: number of aie temp channels that are enabled * @supply_avg_en_attrs: dynamic array of supply averaging enable attribut= es * @temp_avg_en_attrs: dynamic array of temp. sat. averaging enable attrib= utes * @avg_attrs: dynamic array of pointers to averaging attributes @@ -248,6 +250,7 @@ struct sysmon { const unsigned int *oversampling_avail; unsigned int oversampling_num; unsigned int num_supply_chan; + unsigned int num_aie_temp_chan; struct iio_dev_attr *supply_avg_en_attrs; struct iio_dev_attr *temp_avg_en_attrs; struct attribute **avg_attrs; --=20 2.43.0 From nobody Tue Sep 9 21:28:52 2025 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2069.outbound.protection.outlook.com [40.107.237.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 88D691A9FB3; Fri, 5 Sep 2025 08:42:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.237.69 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061748; cv=fail; b=EsZklq/SrIhnbPA/0uqUqmKcUKNcFjY++IYyu6sj1XZ16YKx+JrgAnBslv9H084k7FLrIW3oNFr2GHkcrWYQtTUrsfW56EQz4ZSzHRoPXivKXrfTc+otGxNjBkyC8ciNEplD4wbGdJ4irbxTX5wGdBE6a1BEqPJtVUt89TVm9+0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061748; c=relaxed/simple; bh=+2u6B+o2HjfZcf2ObJXQcFL6uumPIahdfbJ4ULfh1bo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=amRF4u1GvLlEpFzXtngLaICvC0NsUOAT//IYRbJvQyQceaYutEHwTob8XqSzFRw+l1dG1bFWjruPkEyqJgZW1cyxHr0nyXhlUGP1WJEVsHaRKMTukgK1jEXjZR29qLL7y61z/4E76nPp/r3MPGyNQqFWKkLnA27oTjzacToMUoU= 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=Qj9HpBv3; arc=fail smtp.client-ip=40.107.237.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="Qj9HpBv3" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=nedcp1XL3hlFD9aa1KwYfVW/e4ome4MD9nA0TiCxc92hB/tdYe/kHujDk1xxTizV/WVxsHXOqfX7bxBtkYdYsFtJ1Wc5TiawW3ToBCT412ppX1IyIdBSteoXbNhwrhVTVesBZwKA1zD0TMyyBt7janMVveo13sycBcC6JCUaEVkePDtcGVPbs+PYSeYSHSbfKeE2pPodx3QXKZ0su+DBLzf7Mur/Udkgs8yDBoIfYCSaDZwmVuef39x0RzjRhmV8KNL1I6/IgejbyYPSvRSd3zU+GyuL+URcUpTPJrotOj1W1GPVs2Kl0JmjWPUmQqdV3rqInQCmUCmXY4bB4beuEQ== 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=vD7c7XGJ6/A752uiPnxtiGTYcKPl6rIY+JujYapuL/s=; b=zDaEy89qzPz+JN6pz4FNw08fpD6h0Dy/jZA+q738LsMkFANt7fFDCqAlqrWpeIlaSewPNY2JaNdrtfYcZnep+tK6ue5Cj3YAThb9pm6RQ3yDNlAcQUYBEQx7sxqwdYkLkWa8pWlb67wGzAsEP1+KXsWfXxxdg49CTqFDi+ucS0SHZR3CfTe6m3v0xYBSeu7PlnWMAjZIByRAN67LfNoOrjjGVYO57FomhRgKBPzEE0k21C33l2xi7WeSi20GmG4PNDK0iTO6n1WcUIUYlVInlNUtjnRY2jySxg5E7jzwccXNFdzXrOnDVyKgu3SAWWLwPR/+tdup29o+1Byk2fvpCQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.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=vD7c7XGJ6/A752uiPnxtiGTYcKPl6rIY+JujYapuL/s=; b=Qj9HpBv3zey7Mf523nMt1gEUB4CH5wI9E1iNVrSItbv5TgZAOMgdXIQgiENvlOlEO36Osnbs0oXVLcHg2APwCSudAYZcuVh9RrbEUCadE7mPoiQHs8YgmBgFA5B+l1XsRhEL1d0cZaXZ3ZhVt31JuYrLIaJsoJTINzU25MTmmlE= Received: from SJ0PR13CA0028.namprd13.prod.outlook.com (2603:10b6:a03:2c0::33) by IA1PR12MB7613.namprd12.prod.outlook.com (2603:10b6:208:42a::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9094.18; Fri, 5 Sep 2025 08:42:21 +0000 Received: from CO1PEPF000075EF.namprd03.prod.outlook.com (2603:10b6:a03:2c0:cafe::77) by SJ0PR13CA0028.outlook.office365.com (2603:10b6:a03:2c0::33) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9115.7 via Frontend Transport; Fri, 5 Sep 2025 08:42:20 +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=SATLEXMB03.amd.com; pr=C Received: from SATLEXMB03.amd.com (165.204.84.17) by CO1PEPF000075EF.mail.protection.outlook.com (10.167.249.38) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9094.14 via Frontend Transport; Fri, 5 Sep 2025 08:42:20 +0000 Received: from satlexmb10.amd.com (10.181.42.219) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 5 Sep 2025 03:42:12 -0500 Received: from SATLEXMB04.amd.com (10.181.40.145) by satlexmb10.amd.com (10.181.42.219) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1748.10; Fri, 5 Sep 2025 01:42:11 -0700 Received: from localhost (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 via Frontend Transport; Fri, 5 Sep 2025 03:42:11 -0500 From: Michal Simek To: , , , CC: Salih Erim , "Anish Kadamathikuttiyil Karthikeyan Pillai" , Conor Dooley , Daniel Lezcano , "Krzysztof Kozlowski" , Lukasz Luba , "Rafael J. Wysocki" , Rob Herring , Zhang Rui , "open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS" , "open list:THERMAL" Subject: [PATCH 4/6] dt-bindings: thermal: versal: Add description for Versal Thermal Date: Fri, 5 Sep 2025 10:41:47 +0200 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2130; i=michal.simek@amd.com; h=from:subject:message-id; bh=kzf3zxCVMwBg6GlVmTOTrvwZyUlp+2MwNEb6Djv3yEE=; b=owGbwMvMwCG2mv3fB7+vgl8ZT6slMWTsWuRXlB1qe2vZkj6zd7+ty9fVnNjxovmRm+2ZKbfD1 13XkuXb3VHKwiDGwSArpsgynUnHYc23a0vFlkfmw8xhZQIZwsDFKQATiZvNyLD26/nF03+r6M8t eeH4fu3JH1NzkxWnuzdnhc1LfZI4z+o+w/9Ig47HScfl9Bxlzl/g93SYtL2Ib+IHOf9bSTMcmSc ECnIAAA== X-Developer-Key: i=michal.simek@amd.com; a=openpgp; fpr=67350C9BF5CCEE9B5364356A377C7F21FE3D1F91 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CO1PEPF000075EF:EE_|IA1PR12MB7613:EE_ X-MS-Office365-Filtering-Correlation-Id: ac478399-4c49-4c01-130a-08ddec5820a8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|1800799024|82310400026|376014|7416014|13003099007; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?ebgy0BuOhtvpOcl/M9Svwt5goLO6nhIIQEB1aaJ+OE0jmTzq0gJ/Ys/tdyBP?= =?us-ascii?Q?A1bkOBWuqKM37BRODTYQAIlSaFat416ZTm4kt0Oc6eMkUBDVApuOprkAfcNi?= =?us-ascii?Q?ycxrP5J1Szu5fzu1tYhmG5VEmFowfcWMD4jaBhHw485VLdrU1xY0nZhNNiu4?= =?us-ascii?Q?q1gJwKxSGbFXNDEuDO5Wll2Nbe2mQ7NlEaQqzP5ewpRXwrmsBixcS7kiqf75?= =?us-ascii?Q?NeP38/K+RVFgO8gzW+ithNaOQx6fQ777LGFLqRct1YA8hx91ChriMgXDR15S?= =?us-ascii?Q?c3WdnmTOYEs9SFJAErr/xb1uFGCkgL6WErxS1OTSezAB6Tyx+QT73JtvK3Yc?= =?us-ascii?Q?yBqxOXRzfcTeYoOf9DyujRAgyOXpFj6c/wAGPBRQeFpOYoXs7Io9JsriiqtJ?= =?us-ascii?Q?4phuqTPeDXk7KtEHGDNYO5FqoapjxWBoqf6FTL11YVWq++NGySQvKSyaSJMV?= =?us-ascii?Q?Vv8EAJ5r/2IiVXpXU7cjsWP9f33DqNDiNILTlq/fpEuGovBaWg9rxB9/j8dI?= =?us-ascii?Q?i6BePp6/BX/iGIh0tCy1hSLY+TQOpdPHLhC8KBaweglh6cBQblmRnJe8XGC3?= =?us-ascii?Q?9aVwMH8f3y6cJjrPnHkSxWq0DeFzVPPXaMyeyaDzg4UVpIi7aAxEfdLNVv8Y?= =?us-ascii?Q?ECCMZUpWPFBETUNgdKV4IrBzaJm1p+yKE5c/9QP7i4EIlA6yje7dHd7kbniG?= =?us-ascii?Q?IESckbz636iIiTRtq2NnxxU3uDv77TxpALI7kz0+taR9FanlTwH3l5Xl0X28?= =?us-ascii?Q?rMtoUH0fI22nUMniMVALNBQaqjWmCZQ4CbvpDtz1ldFkT/MJf4BZ4MjMX6Dc?= =?us-ascii?Q?WevxGZF7CS9J0EwZzavIlYLop/vPTnu/dZDCrAs7YRSBY8oIzoP6NvEOVasJ?= =?us-ascii?Q?XfFUtIeeM+hZcQhOMGNx4tqjgMJX2dpT3uUr7ozZlULfisPCqQfpYoJeyzp9?= =?us-ascii?Q?Wc0bO2beY7CUO1U65otxXpShZD5eWHcl6rmTy/c58wTKnIKF0kyKl5bkc44j?= =?us-ascii?Q?ViIaaR9pLUyCI4iTN5tBx0otJwqUohQjccqSm5Wo28v3+H6MO1hv+CwTZbV3?= =?us-ascii?Q?A9lNaRyFEv2KTtNOT+5P/VZ9bH+zKRsDjyqDJLBon+u6VDwLzZkZHmRAM8HS?= =?us-ascii?Q?bhKchyVJbnoOiI8CmFQK6n1+iXCe4qR4VLlBmnk3R1LIP5Z8jaRwkV8PD7fM?= =?us-ascii?Q?vZytNfDipa2LZtRu1A5LYK/AN+1MwwdzsETqHxIsW2MjsEloroQXtTFteEYV?= =?us-ascii?Q?BAuItxJ/ZLhrt5ORbL+nIUTC4Ly8a0gwVXBIS8qCaKfCt0LM1Kmr0fuhCPZa?= =?us-ascii?Q?d9dFhD3xd/B7UqtJ9Oh0/hNyYd+4Zw6TyVjQ5kMllDEmSxwLeGn0XI13JD8z?= =?us-ascii?Q?YcIizvQq4FfjIAGzqPsYYSQLRluy5WfEEccE3qNsBt6m+deHKPCyH2eXjCQO?= =?us-ascii?Q?8Hx52yMr7VksuZHlWFEMc6ZhjSLy/pPkrR3gT4RU4gxEpDn51COyWQ=3D=3D?= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB03.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700013)(1800799024)(82310400026)(376014)(7416014)(13003099007);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2025 08:42:20.4280 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ac478399-4c49-4c01-130a-08ddec5820a8 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=[SATLEXMB03.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CO1PEPF000075EF.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB7613 Content-Type: text/plain; charset="utf-8" From: Salih Erim Add description of Versal Thermal which describes IO channels to be binded to thermal. Constant channel of "sysmon-temp-channel" used as mapped iio channel. One temperature zone is used for the AI Engine temperature monitoring. Signed-off-by: Salih Erim Co-developed-by: Anish Kadamathikuttiyil Karthikeyan Pillai Signed-off-by: Anish Kadamathikuttiyil Karthikeyan Pillai Signed-off-by: Michal Simek Acked-by: Conor Dooley --- .../bindings/thermal/xlnx,versal-thermal.yaml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/xlnx,versal-t= hermal.yaml diff --git a/Documentation/devicetree/bindings/thermal/xlnx,versal-thermal.= yaml b/Documentation/devicetree/bindings/thermal/xlnx,versal-thermal.yaml new file mode 100644 index 000000000000..c374d7ae2d2a --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/xlnx,versal-thermal.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/thermal/xlnx,versal-thermal.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Versal Thermal + +maintainers: + - Salih Erim + +description: + Versal Thermal uses Versal Sysmon hardware for temperature reading. + It works as sensor interface to be defined in thermal zones. + +properties: + compatible: + const: xlnx,versal-thermal + + '#thermal-sensor-cells': + const: 1 + + io-channels: + maxItems: 1 + + io-channel-names: + const: sysmon-temp-channel + +required: + - compatible + - '#thermal-sensor-cells' + - io-channels + - io-channel-names + +additionalProperties: false + +examples: + - | + versal-thermal-sensor { + compatible =3D "xlnx,versal-thermal"; + #thermal-sensor-cells =3D <1>; + io-channels =3D <&sysmon0>; + io-channel-names =3D "sysmon-temp-channel"; + }; +... --=20 2.43.0 From nobody Tue Sep 9 21:28:52 2025 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (mail-co1nam11on2083.outbound.protection.outlook.com [40.107.220.83]) (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 E2AAF2C0F6C; Fri, 5 Sep 2025 08:42:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.220.83 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061751; cv=fail; b=B0pmyNNQy3DaWC7KwQC7ApNNpbQ1owOa4+1xGZPgKZQdhTs4n6cGPho2UIVk8HqswCG3erDKJ4Egb1+g1m/xRvzHr9utyCGMwl7yPP4h9oP5w2rtj3A1vqId7axWvXY1VLMsn8oez0ln4gDbOuRuxVC8oCkOykuyBceIPaODPE8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061751; c=relaxed/simple; bh=fAjM/eoF9g8QGhaCy0iT3tNJjI8I2ZoRdMqiAkWx9e0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dTrIx+kjX9WBxZZNA/N0pXMHN9cHtaqP5nc6KvjiE6bV0XaDnYzRsv1xlxOhk0nIrUX5OJxp61LLQ4NgWp00nfN/X9AFIf0Y5pm7HCvdLEHyIFNcUWuq9EA01/iBTswCyP7W3pW01MFXcd0HfzPPngMeJrQ15TGAitItDntahnc= 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=Luz9DPjO; arc=fail smtp.client-ip=40.107.220.83 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="Luz9DPjO" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=tR44nfg+3Io2ftoDNvqdU2x2WzfTpGHP05Vf6jxMnalIEptQzME5nyDAJ1vT76TTnzNDkiRb5loI6RhOqll9odHOSbZmBIVglQ3JTyZugSzhejrO7racmFLNI9F6fs6OwnnvAPyavye0Lwmkz+wqgU/mf6jYSxx/tpt9kgssO+GTqdwrYb9dLNBbmfMk1H5YWbzraYjhNYIXeq4MeWdqyJTo3lHZkiW5HuJEiDmSBcw8YZK3sQAYG6L+2tOXS1jBtF5dW0V9+MJr4l2rs4qkuCJTz5FxhJuGEPv1OPsKa9yBScyTFfPAvPZA6+g7mQbx+evTMy0xCIO/nA0st1KSIw== 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=3zEYK+kcDE3L26umQEkB02w4YFCKNZZ6my1jjC4udyU=; b=DKlm1PUT8sn5SCK4mS3eAciTdxDizveI2cCDjfvKLK+L/wpoCnU34CbTsOB05zq9VBVRAqgVw4UjheBknBX7WhH+V9mI1SRxFPYuOyc2QeD9M6I4zi5W7Vp9Db9AHpv+nJISPAmwJEShsQeJkBU4ilndTPjxpd+M3lBaDLeXn3iM/FAwqpNrVdakNfWd/ag9o/TLb/VapG28iOKfX7EfJu09oCoAHfGF+PHR1IMjka92Vke1NZZ6B+x94+slgdWSdKiInj9rW/ZdUkp8ey/viohVcGwvJ4C8da6AH853x0ZzHj9l83O4cXFNFJH8QYYHE065RtO4UP/a4Lwwh7340Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.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=3zEYK+kcDE3L26umQEkB02w4YFCKNZZ6my1jjC4udyU=; b=Luz9DPjO76r6XOVBWNZV8ooLysGausxTVBoIebFt89FyoA11npuEL8ZWnIM7uMtjcv2gdwEiMtoZEAdeTR2iJjudU0AjF/iOhr0avP5uF/EMlvbqwB5ReZ0g+mozTrxAxZLYjQyVHrLOV2O6wNs++jvdrwt5cgSvxMfwBJ+PIMs= Received: from SJ0PR13CA0055.namprd13.prod.outlook.com (2603:10b6:a03:2c2::30) by CY8PR12MB7562.namprd12.prod.outlook.com (2603:10b6:930:95::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9094.17; Fri, 5 Sep 2025 08:42:26 +0000 Received: from SJ5PEPF000001EB.namprd05.prod.outlook.com (2603:10b6:a03:2c2:cafe::9b) by SJ0PR13CA0055.outlook.office365.com (2603:10b6:a03:2c2::30) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9115.7 via Frontend Transport; Fri, 5 Sep 2025 08:42: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 SJ5PEPF000001EB.mail.protection.outlook.com (10.167.242.199) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9094.14 via Frontend Transport; Fri, 5 Sep 2025 08:42:26 +0000 Received: from SATLEXMB05.amd.com (10.181.40.146) 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; Fri, 5 Sep 2025 03:42:16 -0500 Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB05.amd.com (10.181.40.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.39; Fri, 5 Sep 2025 03:42:14 -0500 Received: from localhost (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 via Frontend Transport; Fri, 5 Sep 2025 03:42:14 -0500 From: Michal Simek To: , , , CC: Salih Erim , Daniel Lezcano , Lukasz Luba , "Rafael J. Wysocki" , Zhang Rui , "open list:THERMAL" Subject: [PATCH 5/6] thermal: versal-thermal: Add Versal thermal driver Date: Fri, 5 Sep 2025 10:41:48 +0200 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5737; i=michal.simek@amd.com; h=from:subject:message-id; bh=7pWFcwQrQwuIrNzh9CkamMKwqRzSh+KygLRRyHiQQB4=; b=owGbwMvMwCG2mv3fB7+vgl8ZT6slMWTsWuT/5dMvE616Znl9vkkfbjafWh55z9bnw9GNSz/Ur JmnG1h7uKOUhUGMg0FWTJFlOpOOw5pv15aKLY/Mh5nDygQyhIGLUwAmwizO8D/wcTuLPO9p4Sx/ B5EpWzXkBY32S0194PrCW6lu9dJmzhUMf8UUFS391t6Z42B+/fuKeVuzBQISDd6qt0ouq73dlNR 9lg0A X-Developer-Key: i=michal.simek@amd.com; a=openpgp; fpr=67350C9BF5CCEE9B5364356A377C7F21FE3D1F91 Content-Transfer-Encoding: quoted-printable Received-SPF: None (SATLEXMB05.amd.com: michal.simek@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001EB:EE_|CY8PR12MB7562:EE_ X-MS-Office365-Filtering-Correlation-Id: ced523ec-91ff-4d3d-4b2b-08ddec582408 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: =?us-ascii?Q?z1K3tkcKzGxQtSMPJSqmgwryrP3mLc1UufKPp2KGz/5zCI0oPArsjmI4UE5H?= =?us-ascii?Q?FCunhosVVhQPaSZmdMhC48c4VXt5VYOpYEf4qy9NNDwfxfG3QlStxGaBgE7J?= =?us-ascii?Q?FKKQhgsfs7S+SqjkI2jhKPFwF9Ir8S/7hf1npWmi/jrTqC1+CHURLqq2Eo++?= =?us-ascii?Q?74b+LW2q15XsVaUUjueRzmAg/sTieXS8IyFg7LeUxNo4Eda8DLy90ACY7xU4?= =?us-ascii?Q?BJg2WqEzZctwBe0ldejkviS4ruM/jYa6THrW6bw1CM5azhblJMaT7R60p4i6?= =?us-ascii?Q?KlAZLO82A/OjENh80KbjfPUcevpynvKskuMHfcUgwu+dg8L5eelLJ5F9KO92?= =?us-ascii?Q?N670c8bcK4vEOLYjd/H65ptLN/9MBEJMk+isGL94OP/o9t6x/3loH55LpOFs?= =?us-ascii?Q?hDtXEYAcoRuT4h3T7wBIvkzRSrw6AofC+1W0zKv4AQehezrpNUMSskHv7NJq?= =?us-ascii?Q?RemL4Csvv8awBfUeThAQYX61szKh2BC+ewXXhGAWLRRT5PJV6n9hZuXTvSMP?= =?us-ascii?Q?rAY70gaU/E/sp9nUGdiwN3Ekwt0M38cQxt5TuSOXBqMcyHDH2itIImNtVYFX?= =?us-ascii?Q?dLO9RrkKgF9PKIj+mFqquZ+zOlCbwM3eKwfyGR+KB2vMDf4bewHQZb85BzNi?= =?us-ascii?Q?hGYyZvM32jJS2gvaL2e4Kx533EzDkzWqywksDdI5lsewG7SEPnx1ECbk1Lk9?= =?us-ascii?Q?LxXPO2Aif4IZhrB8A3au2kohMvsFSjZO6+9qjQiyC6+7PK545ixqy2mrkI8M?= =?us-ascii?Q?QDlcXsywJ4okVRI5BdiOxudn6Cr8AgMqBhu3MA2D/noYy1PJ0mWiGJGevsl4?= =?us-ascii?Q?mDFsfrxKkZMvRVXUf51IxaLFdvYq1T3wb0DE3NKZg1a/tkcSoGZxmZByHyJL?= =?us-ascii?Q?lHR1zJozo9P9JwyFzTFMtoHrtjFf/8PyT94cko1EGTviy1TyV4y/pBaSkQc1?= =?us-ascii?Q?BBNBWjDo1wNAPV5ZXUPrksN+RosOE780wC14PPQO/rL4Xq1GcZq8c02XrSXM?= =?us-ascii?Q?HttvEzZ9cLlvruiK+VMB6xOLR+2+vDEFAnbqvPYiJR46LHjQQpjl5MsWqcsK?= =?us-ascii?Q?Dpi++pys1K5eJ4gJRORlnkzdM7UNnB9nllV67Q7oEOJc2jvhDbqw2rRgeKss?= =?us-ascii?Q?BOTCwy61mBKJjpPWgTAc5jpTP3Iw1L8t4ncWf+7BGsyuFgWbSdR4gyWCFbP/?= =?us-ascii?Q?FhSYESE0eHLC1377Z6iHij/SsLserMZOu2IhyuxBw48Rf0Y3LfZOM5MYC4v7?= =?us-ascii?Q?1QIuR2lq/FbZJ6BlZNrEKwKRPX72zg7OzG81W15r4CN0mwdlNxgCO4zTcwbO?= =?us-ascii?Q?Foae1gfuqVBYjuRLshjIAxIo0EFU6uSHqOQoSSd2Nxt3ru0cVN9sT0mlevTB?= =?us-ascii?Q?Qdft2j6DrX02E/XnqPs2JbCHwifjqblqvTldvcna2F5dHvjMJGOKa3bBZJNQ?= =?us-ascii?Q?CvAr56jQDJ62FkiSc3NXtrzZYfm9twbHf5W3iknuyms+gqESf/vtIramj3yF?= =?us-ascii?Q?LDJPeELvkP65HXXUysCZNP5yiHww3TaUCOIe?= 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: 05 Sep 2025 08:42:26.0931 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ced523ec-91ff-4d3d-4b2b-08ddec582408 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: SJ5PEPF000001EB.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY8PR12MB7562 Content-Type: text/plain; charset="utf-8" From: Salih Erim This patch adds the Versal thermal driver based on Versal Sysmon as thermal infrastructure sensor. Sysmon devices use IIO framework to expose temperature information to system. This driver connects to the sysmon temp channel by iio binding mapping defined on the sysmon driver. This is initial work for defining thermal sensor driver and thermal infrastructure for Versal devices. Single thermal zone has to be defined and no cooling devices and maps are supported at this point. Sysmon devices default temperature event thresholds can be used as temperature ranges. Updates the maintainer file accordingly to this driver. Signed-off-by: Salih Erim Signed-off-by: Michal Simek --- MAINTAINERS | 6 +++ drivers/thermal/Kconfig | 12 +++++ drivers/thermal/Makefile | 1 + drivers/thermal/versal_thermal.c | 87 ++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 drivers/thermal/versal_thermal.c diff --git a/MAINTAINERS b/MAINTAINERS index 1a9c5549d0dc..907a6c193fb7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -27609,6 +27609,12 @@ F: Documentation/devicetree/bindings/iio/adc/xlnx,= versal-sysmon.yaml F: drivers/iio/adc/versal-sysmon* F: include/linux/iio/adc/versal-sysmon-events.h =20 +XILINX VERSAL THERMAL DRIVER +M: Salih Erim +S: Maintained +F: Documentation/devicetree/bindings/thermal/xlnx,versal-thermal.yaml +F: drivers/thermal/versal_thermal.c + XILINX UARTLITE SERIAL DRIVER M: Peter Korsgaard L: linux-serial@vger.kernel.org diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index a09c188b9ad1..9695ecec8f04 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -517,4 +517,16 @@ config LOONGSON2_THERMAL is higher than the high temperature threshold or lower than the low temperature threshold, the interrupt will occur. =20 +config VERSAL_THERMAL + tristate "Versal thermal sensor driver" + depends on OF + depends on VERSAL_SYSMON + help + This adds support for Versal thermal driver as thermal zone sensor + The thermal driver is connected to Versal Sysmon for the temperature + channel via iio binding. The Sysmon channel is read via IIO framework + and the channel information is provided to driver. + The driver can also be build as a module. If so, the module will be cal= led + versal_thermal + endif diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index d7718978db24..407c84aa2691 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -68,3 +68,4 @@ obj-$(CONFIG_SPRD_THERMAL) +=3D sprd_thermal.o obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL) +=3D khadas_mcu_fan.o obj-$(CONFIG_LOONGSON2_THERMAL) +=3D loongson2_thermal.o obj-$(CONFIG_THERMAL_CORE_TESTING) +=3D testing/ +obj-$(CONFIG_VERSAL_THERMAL) +=3D versal_thermal.o diff --git a/drivers/thermal/versal_thermal.c b/drivers/thermal/versal_ther= mal.c new file mode 100644 index 000000000000..51c8586af5a4 --- /dev/null +++ b/drivers/thermal/versal_thermal.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AMD Versal Thermal Driver for Versal Devices + * + * Copyright (C) 2024 - 2025 Advanced Micro Devices, Inc. + */ + +#include +#include +#include + +#include "thermal_hwmon.h" + +#define SYSMON_TEMP_CH_NAME "sysmon-temp-channel" +#define SYSMON_FRACTIONAL_DENOM 128 + +struct versal_thermal_info { + struct device *dev; + struct thermal_zone_device *tzd; + struct iio_channel *channel; +}; + +static int temperature_sensor_get_temp(struct thermal_zone_device *tz, int= *temp) +{ + struct versal_thermal_info *vti =3D thermal_zone_device_priv(tz); + int ret, val; + + ret =3D iio_read_channel_processed(vti->channel, &val); + if (ret =3D=3D IIO_VAL_FRACTIONAL) { + /* Convert raw value to temperature in millidegrees Celsius */ + *temp =3D val * 1000; + *temp /=3D SYSMON_FRACTIONAL_DENOM; + } else if (ret =3D=3D IIO_VAL_INT) { + *temp =3D val; + } else { + dev_err(vti->dev, "iio_read_channel_processed failed, ret code =3D %d\n"= , ret); + return ret; + } + return 0; +} + +static const struct thermal_zone_device_ops thermal_zone_ops =3D { + .get_temp =3D temperature_sensor_get_temp, +}; + +static int versal_thermal_probe(struct platform_device *pdev) +{ + struct versal_thermal_info *vti; + + vti =3D devm_kzalloc(&pdev->dev, sizeof(struct versal_thermal_info), GFP_= KERNEL); + if (!vti) + return -ENOMEM; + + vti->channel =3D devm_iio_channel_get(&pdev->dev, SYSMON_TEMP_CH_NAME); + if (IS_ERR(vti->channel)) + return dev_err_probe(&pdev->dev, PTR_ERR(vti->channel), + "IIO channel not found\n"); + + vti->dev =3D &pdev->dev; + + vti->tzd =3D devm_thermal_of_zone_register(&pdev->dev, 0, vti, &thermal_z= one_ops); + if (IS_ERR(vti->tzd)) + return dev_err_probe(&pdev->dev, PTR_ERR(vti->tzd), + "Thermal zone sensor register failed\n"); + + return devm_thermal_add_hwmon_sysfs(&pdev->dev, vti->tzd); +} + +static const struct of_device_id versal_thermal_of_match[] =3D { + { .compatible =3D "xlnx,versal-thermal", }, + { /* end of list */ }, +}; +MODULE_DEVICE_TABLE(of, versal_thermal_of_match); + +static struct platform_driver versal_thermal_driver =3D { + .driver =3D { + .name =3D "versal-thermal", + .of_match_table =3D versal_thermal_of_match, + }, + .probe =3D versal_thermal_probe, +}; + +module_platform_driver(versal_thermal_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("XILINX Versal Thermal Driver"); +MODULE_AUTHOR("Advanced Micro Devices, Inc"); --=20 2.43.0 From nobody Tue Sep 9 21:28:52 2025 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on2079.outbound.protection.outlook.com [40.107.244.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 807DF2FD1A4; Fri, 5 Sep 2025 08:42:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.244.79 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061752; cv=fail; b=CqkMJ45Dg8OBhIflD2xD2C6lMgriNyLt3ZY/5HyF/Ie24WLSJopvgWSq9IpCHI3W3azwYpLMoPPGk07Ofe52m69nnVW1qA72eU2zhqvEa+sB3fR894iiBObInM2R4Ltki1rqbkGz4avEIb1tRWpXXrkVDoIMysE5knxZ/laFCL8= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757061752; c=relaxed/simple; bh=Dyt5y0suYIyDUsq0NUH1npcXpRh6PGIDLdvT7/GWuuM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OM7IvJxJe7udqUeNsVXt8/ISFqemrZol8sO6/08EmvXNrduxHOMCoOo5YnL6kfgusJyzQrkXGvI7QE+60hBofiFkU/QoEs9CjhbJaB41lZJ9/GXh7DZKG2a/QXG0pw2TiBZ0ns150lAkXYjE4SD1D1PBKrdSQk4wM+aQ/PLaPIo= 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=cyz/49VI; arc=fail smtp.client-ip=40.107.244.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="cyz/49VI" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=T7U51RTXgilCjb3hF5w2Fcon4tlF0JOrT15hRwY26wcIUXMNxA1+8INQunEuYsRVdEAUZZwX1Vp0gx18hZDThfKvnOOitZggjg47OCtXLmqDkYJijda73PjodI7ye4osChFF5BNAi7ntjjvhoG35GZ6perlW1X3gXRofkVRlPnmRLJRN3caT1TZtvv2xtWDZIw4pGAOVQgUJGjRfqIuckZ1mW1z1QLY+jpkf4Yupgvji4SdtS44aBCkmXqh/g99caZHsIl6ZkktGAhFcYbcOWTR/9tvPyfoHaU146jgXB+Hd5LV7CkxqA51E2SmNzAmndy+9y3t6G9d+aCGWAG9RQg== 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=1/oELYW9JzWQN/gA2KF8BfscCEjLAMT1CHowL87kgmI=; b=Nd8gFsezz7MEgu4pYqcMLCvtg10LXYGMcYFYhThVPwk+mZc9mrcLgTVRFJykP42vhlDE9+WC75rdzSvqRPqfEKYxozGvjOmcfYmIv19afaNLyTmJXoKNuoXJ2YfNQAd0ksXPU1BoOZd8x9b2fuWSWS+fVCw5ZIyDYAPpQEToHQ0E3V7P3Ir15u+iCml7u3uRFUfTmxjTno2SFd2U7Ob+f5JKtyuC46zILlaAmv/2l0gSL74oCK7sVp90N97gRaguI+O/Jng2XyztAFpyMl1n7SrExs1QvcBnailLZyQ3mDdTFd6EylXx08nBJQ95LLimPUSqpexKMgb0GzbwnctFwA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=vger.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=1/oELYW9JzWQN/gA2KF8BfscCEjLAMT1CHowL87kgmI=; b=cyz/49VIVwD1SAtKNIsyK2vbeR32F7vGSo5t4kLz3WifX+tr+HBswJ1vnzHKzWSHT2+sgHMlqi4tyhvwj9At+ZVs4Nbz/VlM7GB+YUO8xWWdbgwIUOXWwqG0ObpI1X5CcGwETS8V5z3faHNJMnYOkVXZICkAUuljj2xoFtfhdvk= Received: from MW4PR03CA0271.namprd03.prod.outlook.com (2603:10b6:303:b5::6) by DS0PR12MB8341.namprd12.prod.outlook.com (2603:10b6:8:f8::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9094.17; Fri, 5 Sep 2025 08:42:26 +0000 Received: from SJ5PEPF000001ED.namprd05.prod.outlook.com (2603:10b6:303:b5:cafe::ef) by MW4PR03CA0271.outlook.office365.com (2603:10b6:303:b5::6) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9073.27 via Frontend Transport; Fri, 5 Sep 2025 08:42:26 +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 SJ5PEPF000001ED.mail.protection.outlook.com (10.167.242.201) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.9094.14 via Frontend Transport; Fri, 5 Sep 2025 08:42:26 +0000 Received: from Satlexmb09.amd.com (10.181.42.218) 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; Fri, 5 Sep 2025 03:42:18 -0500 Received: from SATLEXMB04.amd.com (10.181.40.145) by satlexmb09.amd.com (10.181.42.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.2.1748.10; Fri, 5 Sep 2025 01:42:17 -0700 Received: from localhost (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 via Frontend Transport; Fri, 5 Sep 2025 03:42:17 -0500 From: Michal Simek To: , , , CC: Anish Kadamathikuttiyil Karthikeyan Pillai , Daniel Lezcano , Lukasz Luba , "Rafael J. Wysocki" , Salih Erim , Zhang Rui , "open list:THERMAL" Subject: [PATCH 6/6] thermal: versal-thermal: Support thermal management in AI Engine Date: Fri, 5 Sep 2025 10:41:49 +0200 Message-ID: <3636099d5d0b31ebf232a5b2e741f0ff7e7e1631.1757061697.git.michal.simek@amd.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7486; i=michal.simek@amd.com; h=from:subject:message-id; bh=5K+W4GHGtS5R3x94A8Z6tkUi1JHOqC0CMj/luPxKWkY=; b=owGbwMvMwCG2mv3fB7+vgl8ZT6slMWTsWuSvlZPrfm5qad91Jfb6V+X5by4fuKQ3qT+nydLR6 8WiS1ckOkpZGMQ4GGTFFFmmM+k4rPl2banY8sh8mDmsTCBDGLg4BWAiO5Yy/A+wdTxyWdNU9m64 Ucyvh9Ob+1SiJp62/HtafeG6pnkMS9oZ/sovTnq+KdW79MfssJI7Iukbe3jtIvdsSVO2LkraLmJ tyQkA X-Developer-Key: i=michal.simek@amd.com; a=openpgp; fpr=67350C9BF5CCEE9B5364356A377C7F21FE3D1F91 Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ5PEPF000001ED:EE_|DS0PR12MB8341:EE_ X-MS-Office365-Filtering-Correlation-Id: 4ea29b1e-19e5-4e9f-0b22-08ddec582418 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700013|82310400026|1800799024|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?9QuBfwF1+4iTdQfOFz9XwXTfsIshgKYlugllaH88JrHJtFLX0XOuqOzCNlxX?= =?us-ascii?Q?s8TFWAeSC2RNJ7D5+B8s3hZ0K+mDFrQcOFMmFtAjLTgwR1YYVJx3wZfaQQ58?= =?us-ascii?Q?gTLgqFdFMrC3E+sHpv1A1nDngpOZ94iHPXZ1SFbmFI+lekJYf03S9C6Cj7Tv?= =?us-ascii?Q?zoOPC7oKz8lxJPCzgqhXvx4IRWKkV5SH1YJsuV59Tfhpm9h0gOaH2Dy2ihTr?= =?us-ascii?Q?MiwzbwvHCWABNbU82YtZFaCXF0WkGRXQDC5Lq2HGk5hvPnYitQHX3+ShU4I+?= =?us-ascii?Q?jce2+9aSKDQSNwQqcXpQw3UG/twRe07kvhgi7KfuTncykKY3zJPOb/vS4roA?= =?us-ascii?Q?1XBZ0JsQXXhH8wRpL5Vwrika2UJe8ljTp6Kb69+1/eDEZhd+SqcUdrprVfkZ?= =?us-ascii?Q?gjnUPI0jgFNhHHJyKpOVKSqki33ub8eNB+sU+hcNiL9DY7IrG5DcHLbw4aRB?= =?us-ascii?Q?mdmVktqjlVoW+o4gJBAj/5yTF0ZfVWmsHtpPt2eDdcYDbecZGXPKpwOpnXNA?= =?us-ascii?Q?3NUj5obFBKM+5puINg0HGxtc33nttjrMmg68kja3wWkdeu2xzNi6zW4ukc2U?= =?us-ascii?Q?U5Gct4OHkBfzKOloR/UFJkwf0zLrak03b4USf+tjbpa8PejD05lsPfAkv/wh?= =?us-ascii?Q?MGpVPa/qFiFJvLd8HyMJdZqWeL3MeaT7apNVCgQiG4VVtMDXqXGWVUseh3Y0?= =?us-ascii?Q?MGiwtPrKFDhtyxhPxXgNtC72o6tBesn40HT63ZD8ziRpQfu3KTUjamzSCeuk?= =?us-ascii?Q?wdF5ippUk8RaA+NQAZFsLiZsq+ANrJPVPkrzcORgMMtFHJUxfSpFbkNXQizU?= =?us-ascii?Q?zyxUslv+WIuCgCGXwC8StQRMygzIa4TcpHw9c9byaoVmDGON5UJ8SCHE+dJU?= =?us-ascii?Q?+jpG6ujhHoeY1QnDKwY+usGCrgn0mWFLEGsUws/eltwXw0J03aoWMB5HFjrY?= =?us-ascii?Q?UwLeoHWUe7loH3Id5JXXPwxr7DJbwfYio316kWwYmtAM6mt3aH1zZqczaf9J?= =?us-ascii?Q?2aZFhWjC9q3jT93LNoVeORK/SDFWCeNSKwY8ptA26kVyBKUCF6KXW2V+DkYB?= =?us-ascii?Q?ZmcpO7XaQ5bEgYlur+5hXvU0MDSVaoGML3ZYSHD2WJ8w087x6WHKvGPy9LeP?= =?us-ascii?Q?fK89V/xZomKpCsT2FEX4wbBOvo9wkPTrT9wTLq/3zHwRrcgzAISFrTLspJSK?= =?us-ascii?Q?2tYitqMZ/lOIJ+y1+M84ptndL5+Pq2PS0cigOqt8YNIhO7pWKlTiW7To5BQN?= =?us-ascii?Q?qEPNBB3S5kVROqvIWC7PR1llANICcSAO1e9vnEsvDQlbIZnVhDNpMDBznpX1?= =?us-ascii?Q?0B20WeievSjsF43BPmxIfvCcIOcKA7MQ1NT3ODvM6j6iII/oi0gwey+SBAhh?= =?us-ascii?Q?MargxClmY8iwOrYve8JxvgxOEibK3JxmkkeP0buPF4HSeByCYh9XpbSRzwWe?= =?us-ascii?Q?sVf9FDFXWNu7ikGc+DrI+oLPJMznhy5V5az59g2y8SlTYFBVxIjgMfTJcYVb?= =?us-ascii?Q?tAUYjIzd1XcS+LIqv2cbnQ2IU7NuR8+E6LZy?= 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)(36860700013)(82310400026)(1800799024)(376014);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Sep 2025 08:42:26.1963 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4ea29b1e-19e5-4e9f-0b22-08ddec582418 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: SJ5PEPF000001ED.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR12MB8341 Content-Type: text/plain; charset="utf-8" From: Anish Kadamathikuttiyil Karthikeyan Pillai For AI Engine thermal monitoring, through the thermal framework, a new temperature zone is added. The temperature of versal sysmon satellites near to AI Engine is read from the mapped IIO channels. The maximum value of temperature from versal sysmon satellites near AI Engine will be reported. In versal thermal driver iio channel names are read from versal sysmon temp child node. The reason is we cannot specify the iio-channel-names in versal thermal sensor node, as it can change from board to board and versal_thermal node which is not related to any hardware. Passing NULL is not be supported by devm_ API for getting IIO channel names. So we moved from this approach to iio_channel_get approach. Signed-off-by: Anish Kadamathikuttiyil Karthikeyan Pillai Signed-off-by: Michal Simek --- drivers/thermal/versal_thermal.c | 146 +++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 6 deletions(-) diff --git a/drivers/thermal/versal_thermal.c b/drivers/thermal/versal_ther= mal.c index 51c8586af5a4..e2e201c5c955 100644 --- a/drivers/thermal/versal_thermal.c +++ b/drivers/thermal/versal_thermal.c @@ -13,11 +13,17 @@ =20 #define SYSMON_TEMP_CH_NAME "sysmon-temp-channel" #define SYSMON_FRACTIONAL_DENOM 128 +#define SYSMON_STATIC_IIO_CH_COUNT 1 +#define SYSMON_AIE_TEMP_CH 200 +#define TEMP_MAX 160 =20 struct versal_thermal_info { struct device *dev; struct thermal_zone_device *tzd; + struct thermal_zone_device *tzd_aie; struct iio_channel *channel; + struct iio_channel **channel_aie; + u32 num_aie_channels; }; =20 static int temperature_sensor_get_temp(struct thermal_zone_device *tz, int= *temp) @@ -39,31 +45,158 @@ static int temperature_sensor_get_temp(struct thermal_= zone_device *tz, int *temp return 0; } =20 +static int temperature_sensor_get_temp_aie(struct thermal_zone_device *tz, + int *temp) +{ + struct versal_thermal_info *vti =3D thermal_zone_device_priv(tz); + int ret, val; + int max_temp =3D INT_MIN; + u32 aie_ch_index; + + for (aie_ch_index =3D 0; aie_ch_index < vti->num_aie_channels; + aie_ch_index++) { + ret =3D iio_read_channel_processed(vti->channel_aie[aie_ch_index], &val); + if (ret =3D=3D IIO_VAL_FRACTIONAL) { + /* Convert raw value to temperature in millidegrees Celsius */ + *temp =3D val * 1000; + *temp /=3D SYSMON_FRACTIONAL_DENOM; + } else if (ret =3D=3D IIO_VAL_INT) { + *temp =3D val; + } else { + dev_err(vti->dev, "iio_read_channel_processed failed aie ch%d, ret =3D = %d\n", + aie_ch_index, ret); + return ret; + } + if (*temp > max_temp) + max_temp =3D *temp; + } + *temp =3D max_temp; + return 0; +} + static const struct thermal_zone_device_ops thermal_zone_ops =3D { .get_temp =3D temperature_sensor_get_temp, }; =20 +static const struct thermal_zone_device_ops thermal_zone_ops_aie =3D { + .get_temp =3D temperature_sensor_get_temp_aie, +}; + +static void versal_thermal_iio_chan_release(struct versal_thermal_info *vt= i) +{ + int aie_ch_index; + + if (!IS_ERR_OR_NULL(vti->channel)) + iio_channel_release(vti->channel); + for (aie_ch_index =3D 0; aie_ch_index < vti->num_aie_channels; aie_ch_ind= ex++) + if (!IS_ERR_OR_NULL(vti->channel_aie[aie_ch_index])) + iio_channel_release(vti->channel_aie[aie_ch_index]); +} + static int versal_thermal_probe(struct platform_device *pdev) { struct versal_thermal_info *vti; + struct device_node *sysmon_node; + struct device_node *child_node =3D NULL; + int aie_ch_index =3D 0; + int ret =3D 0; + u32 num_aie_channels =3D 0; + const char **aie_temp_chan_names; + const char *aie_temp_chan_name; =20 vti =3D devm_kzalloc(&pdev->dev, sizeof(struct versal_thermal_info), GFP_= KERNEL); if (!vti) return -ENOMEM; =20 - vti->channel =3D devm_iio_channel_get(&pdev->dev, SYSMON_TEMP_CH_NAME); - if (IS_ERR(vti->channel)) - return dev_err_probe(&pdev->dev, PTR_ERR(vti->channel), - "IIO channel not found\n"); - vti->dev =3D &pdev->dev; =20 + vti->channel =3D iio_channel_get(NULL, SYSMON_TEMP_CH_NAME); + if (IS_ERR(vti->channel)) { + vti->num_aie_channels =3D 0; + versal_thermal_iio_chan_release(vti); + return dev_err_probe(&pdev->dev, PTR_ERR(vti->channel), + "IIO channel %s not found\n", + SYSMON_TEMP_CH_NAME); + } + vti->tzd =3D devm_thermal_of_zone_register(&pdev->dev, 0, vti, &thermal_z= one_ops); if (IS_ERR(vti->tzd)) return dev_err_probe(&pdev->dev, PTR_ERR(vti->tzd), "Thermal zone sensor register failed\n"); =20 - return devm_thermal_add_hwmon_sysfs(&pdev->dev, vti->tzd); + ret =3D devm_thermal_add_hwmon_sysfs(&pdev->dev, vti->tzd); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "Failed to add hwmon sysfs for sysmon temp\n"); + + sysmon_node =3D of_find_node_by_name(NULL, "sysmon"); + if (sysmon_node) { + ret =3D of_property_read_u32(sysmon_node, "xlnx,numaiechannels", + &num_aie_channels); + if (ret < 0) + num_aie_channels =3D 0; + } + + if (num_aie_channels > 0) { + aie_temp_chan_names =3D devm_kcalloc(&pdev->dev, num_aie_channels, + sizeof(*aie_temp_chan_names), + GFP_KERNEL); + if (!aie_temp_chan_names) + return -ENOMEM; + + for_each_child_of_node(sysmon_node, child_node) { + if (of_property_present(child_node, "xlnx,aie-temp")) { + ret =3D of_property_read_string(child_node, "xlnx,name", + &aie_temp_chan_name); + if (ret < 0) { + of_node_put(child_node); + return ret; + } + aie_temp_chan_names[aie_ch_index] =3D aie_temp_chan_name; + aie_ch_index++; + } + } + + /* Allocate memory for the dynamic aie temperature channels */ + vti->channel_aie =3D devm_kcalloc(&pdev->dev, num_aie_channels, + sizeof(*vti->channel_aie), GFP_KERNEL); + if (!vti->channel_aie) + return -ENOMEM; + + for (aie_ch_index =3D 0; aie_ch_index < num_aie_channels; aie_ch_index++= ) { + vti->channel_aie[aie_ch_index] =3D + iio_channel_get(NULL, aie_temp_chan_names[aie_ch_index]); + if (IS_ERR(vti->channel_aie[aie_ch_index])) { + vti->num_aie_channels =3D aie_ch_index + 1; + versal_thermal_iio_chan_release(vti); + return dev_err_probe(&pdev->dev, + PTR_ERR(vti->channel_aie[aie_ch_index]), + "IIO AIE TEMP channel %s not found\n", + aie_temp_chan_names[aie_ch_index]); + } + } + + vti->tzd_aie =3D devm_thermal_of_zone_register(&pdev->dev, 1, vti, + &thermal_zone_ops_aie); + if (IS_ERR(vti->tzd_aie)) + return dev_err_probe(&pdev->dev, PTR_ERR(vti->tzd_aie), + "Failed to register thermal zone aie temp\n"); + + ret =3D devm_thermal_add_hwmon_sysfs(&pdev->dev, vti->tzd_aie); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "Failed to add hwmon sysfs for aie temp\n"); + } + vti->num_aie_channels =3D num_aie_channels; + platform_set_drvdata(pdev, vti); + return 0; +} + +static void versal_thermal_remove(struct platform_device *pdev) +{ + struct versal_thermal_info *vti =3D platform_get_drvdata(pdev); + + versal_thermal_iio_chan_release(vti); } =20 static const struct of_device_id versal_thermal_of_match[] =3D { @@ -78,6 +211,7 @@ static struct platform_driver versal_thermal_driver =3D { .of_match_table =3D versal_thermal_of_match, }, .probe =3D versal_thermal_probe, + .remove =3D versal_thermal_remove, }; =20 module_platform_driver(versal_thermal_driver); --=20 2.43.0