From nobody Sat Jul 25 03:21:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 59B10533D6; Mon, 20 Jul 2026 00:38:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784507905; cv=none; b=EkfoXSLMojOAd857FKLIhs3MqqmUnjlRIUlGt+QRHJdfR20epHV+mqAEr7tnFbSNFzaPbRjqckdZf+e0fhoQUH/4llMZk5sVmRATx1ZUbQKSFM0vXqxUYV4mL8kPYr/CIsV67w0seCtR168f5SSK5iMoM912BhTwLVw+sIJNcJA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784507905; c=relaxed/simple; bh=sVLL5zFhnEf2mpOMRpAU0zuPeayxIDNDpPLwPVLqsX4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=d5gzjvXJA5QEs3/YoNNxLFZfZXp+/6PCnSWtYoWI7OcCIv6kI7gB7oir4shEJjB+W2kg+TkBc7HCauImu03FdZdvpBvbHKNCXCnCN5hxG0Ny6fGabENwGOCrSVW39GrPlV9fR0T5eHrKck3N3tu+T1wOkq63tKZ/Llhaw++Sj8U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pOUjsRDi; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pOUjsRDi" Received: by smtp.kernel.org (Postfix) with ESMTPS id 28597C2BCF7; Mon, 20 Jul 2026 00:38:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1784507905; bh=sVLL5zFhnEf2mpOMRpAU0zuPeayxIDNDpPLwPVLqsX4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=pOUjsRDiHy0JadQvnzOg8PzdMsnhuT+PeYmZDcxCNgxmYPXQXb9lKpiY1+BzBUiNz 8RJVRZ3qoiHzQlTI5XhOttPX/5vzLtu6vlKdO8mq2zUu9+NeBTmbtqNeyEVCUqhHml V02qC2yWHP+NZG6cT7ICEH/qBgxqilM64CuImCdBXOuJidZIqyXBR6xgSyRTmAV9fo L/hmP/dDH6GA83FNcBFWw9VR16BRolaAAONoQqt2iA3RwITBhmsqY7T4FGCmiwp02E L/O8hwQ1ab/0I1fuXm12TXWe9iHjj9zWH1D9p7o30dQU551FtDuguudtkmEhhaNV16 2hop0j+ukX/qg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E687DC44512; Mon, 20 Jul 2026 00:38:24 +0000 (UTC) From: Jia Wang via B4 Relay Date: Mon, 20 Jul 2026 08:38:04 +0800 Subject: [PATCH v4 1/3] clk: composite: Export devm composite pdata helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-ultrarisc-clock-v4-1-fe639d63bbac@ultrarisc.com> References: <20260720-ultrarisc-clock-v4-0-fe639d63bbac@ultrarisc.com> In-Reply-To: <20260720-ultrarisc-clock-v4-0-fe639d63bbac@ultrarisc.com> To: Michael Turquette , Stephen Boyd , Brian Masney , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jia Wang X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784507902; l=845; i=wangjia@ultrarisc.com; s=20260515; h=from:subject:message-id; bh=mmNYdl//tm5jVxgVHLR5oIpB4MdMweBH1Jbb6olZW8U=; b=805WxaH5WTkCWtyOv0d+xqNS/6rgmIa8Pn5/DAoxqF9NAsDUOIPyvRF9xHW2+peiVPbQJ2D1w qMDlpUBydL9C8j0gfz5Lx38X/NsQDpMsAZjsoxjjFweorLTWUEW1IH6 X-Developer-Key: i=wangjia@ultrarisc.com; a=ed25519; pk=wGVm18siRScehKOkOz0WKxgxDy7IezHEszhnN4/TUCY= X-Endpoint-Received: by B4 Relay for wangjia@ultrarisc.com/20260515 with auth_id=779 X-Original-From: Jia Wang Reply-To: wangjia@ultrarisc.com From: Jia Wang Allow modular clock drivers to use devm_clk_hw_register_composite_pdata() by exporting the helper. The non-devm composite helpers are already available to modules. Export this devm variant as well so users do not need to open-code devres cleanup. Signed-off-by: Jia Wang Reviewed-by: Brian Masney --- drivers/clk/clk-composite.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 835b1e4e5869..11842bce5918 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -462,3 +462,4 @@ struct clk_hw *devm_clk_hw_register_composite_pdata(str= uct device *dev, rate_hw, rate_ops, gate_hw, gate_ops, flags); } +EXPORT_SYMBOL_GPL(devm_clk_hw_register_composite_pdata); --=20 2.34.1 From nobody Sat Jul 25 03:21:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 9D0AF1B85F8; Mon, 20 Jul 2026 00:38:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784507905; cv=none; b=QvE3cbzex3+K/h7e8EJq3utuXHRE7v4ZeqCN/vOBBYL6tmZxq0+ZzgJSdRdQXnrqTyf1bj5sTY7he3Ej8kxFUKbRUkQvi8OD7I4xjg4yfCtVA6blIxF+We8AKnikdhBNjYxpGuFlJntlu9dMSgSQ01qjxL3wXycAKtG3frfp6iQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784507905; c=relaxed/simple; bh=ndlFAPnsB0Fq6i2L0rhg60nuodlsSu9z7E3c34glIHY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=B3ugHUiWlRd5qX7/zaSApDAUEfrCKrdxmRKwYapXnkkdnH2I8mSxRA6k12HGw/eiMyZoSc4IJ3tY+VtZunCViBp92LDESmH05RQ5TdzTdK4pAhuoMY8oTlvvI9s/qyJOgsqs7zFdUMrIRPPfuOCO/ES1AjqNHEGveujpWmfTCcg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VS8hEoEn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VS8hEoEn" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7355EC2BCFB; Mon, 20 Jul 2026 00:38:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1784507905; bh=ndlFAPnsB0Fq6i2L0rhg60nuodlsSu9z7E3c34glIHY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=VS8hEoEnQQffnYozLkoytwcDdwC3euxuNmswfGawtY4NY/mCliKQUdooDfI9dlkQO pkg6QTg40WZSmPxv9EqUq2nK2PYi241ZrCmydYfvOpDJannVP1cVSIgUKSr3AQjsCY eUB20V1a897QqzKzxA9Z1nboXSIi6lb40dA4Z3AuTC2iUVjMF/w5wYpyJHzsaPN12Z 6Mt7juNVP6eLxi6a5WtTd9YMp9Wj3JBwviBdZZpV+NZP0Cb9MeEtG9v2xV+vLi5xr5 RsWEb8sEqLlllZhBqiVytg5um+t16+Gc9uolVOEPWW2Spw/rUuj9890DUwP/2PGKEc 5JL0M51lzTIWQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5346DC4451B; Mon, 20 Jul 2026 00:38:25 +0000 (UTC) From: Jia Wang via B4 Relay Date: Mon, 20 Jul 2026 08:38:05 +0800 Subject: [PATCH v4 2/3] dt-bindings: clock: ultrarisc: Add DP1000 Clock Controller Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-ultrarisc-clock-v4-2-fe639d63bbac@ultrarisc.com> References: <20260720-ultrarisc-clock-v4-0-fe639d63bbac@ultrarisc.com> In-Reply-To: <20260720-ultrarisc-clock-v4-0-fe639d63bbac@ultrarisc.com> To: Michael Turquette , Stephen Boyd , Brian Masney , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jia Wang , Conor Dooley X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784507902; l=4082; i=wangjia@ultrarisc.com; s=20260515; h=from:subject:message-id; bh=hAYITNry4LyDjLKPqs+Vj2CAziH/un6ry4g7V+jxfJw=; b=wVgjPUbxJsYXi8ofcrPzrpWRi8YHJHQM5Lgii+YOcxry/JbDXczw3o2iqJL4cSUBmyDjTRWuG nlrFqoYHNloDQPl4t4Vl/PbOm34xIY8hWlSDpQ2dbSNDPPVASD7QWRS X-Developer-Key: i=wangjia@ultrarisc.com; a=ed25519; pk=wGVm18siRScehKOkOz0WKxgxDy7IezHEszhnN4/TUCY= X-Endpoint-Received: by B4 Relay for wangjia@ultrarisc.com/20260515 with auth_id=779 X-Original-From: Jia Wang Reply-To: wangjia@ultrarisc.com From: Jia Wang Add doc for the clock controller on the UltraRISC DP1000 RISC-V SoC. Signed-off-by: Jia Wang Reviewed-by: Conor Dooley --- .../bindings/clock/ultrarisc,dp1000-clk.yaml | 60 ++++++++++++++++++= ++++ MAINTAINERS | 7 +++ include/dt-bindings/clock/ultrarisc,dp1000-clk.h | 27 ++++++++++ 3 files changed, 94 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.y= aml b/Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml new file mode 100644 index 000000000000..ede565ec440c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ultrarisc,dp1000-clk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: UltraRISC DP1000 Clock Controller + +maintainers: + - Jia Wang + +description: | + The UltraRISC DP1000 clock controller is driven from a single external + oscillator input. It provides a system PLL with fractional multiplier + and post-divider stages, several fixed-ratio derived clocks for + the on-chip subsystem, Clock Configuration Register (CCR) divider + outputs for GMAC and the UART, I2C, and SPI root clocks, and + per-instance gate clocks for UART0-3, I2C0-3, and SPI0-1. + + All available clocks are defined as preprocessor macros in + include/dt-bindings/clock/ultrarisc,dp1000-clk.h + +properties: + compatible: + const: ultrarisc,dp1000-clk + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + description: + External oscillator input clock used as the parent of the PLLs. + + "#clock-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - "#clock-cells" + +additionalProperties: false + +examples: + - | + #include + + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + clock-controller@11080000 { + compatible =3D "ultrarisc,dp1000-clk"; + reg =3D <0x0 0x11080000 0x0 0x1000>; + clocks =3D <&osc>; + #clock-cells =3D <1>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 806bd2d80d15..d646707bb17f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -27671,6 +27671,13 @@ S: Maintained F: drivers/usb/common/ulpi.c F: include/linux/ulpi/ =20 +ULTRARISC DP1000 CLOCK DRIVER +M: Jia Wang +L: linux-clk@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml +F: include/dt-bindings/clock/ultrarisc,dp1000-clk.h + ULTRARISC DP1000 PINCTRL DRIVER M: Jia Wang L: linux-gpio@vger.kernel.org diff --git a/include/dt-bindings/clock/ultrarisc,dp1000-clk.h b/include/dt-= bindings/clock/ultrarisc,dp1000-clk.h new file mode 100644 index 000000000000..751125f99965 --- /dev/null +++ b/include/dt-bindings/clock/ultrarisc,dp1000-clk.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +#ifndef _DT_BINDINGS_CLOCK_ULTRARISC_DP1000_CLK_H +#define _DT_BINDINGS_CLOCK_ULTRARISC_DP1000_CLK_H + +#define DP1000_CLK_SYSPLL 0 +#define DP1000_CLK_SYSPLL_DIV2 1 +#define DP1000_CLK_SUBSYS 2 +#define DP1000_CLK_GMAC 3 +#define DP1000_CLK_UART_ROOT 4 +#define DP1000_CLK_I2C_ROOT 5 +#define DP1000_CLK_SPI_ROOT 6 +#define DP1000_CLK_PCIE_DBI 7 +#define DP1000_CLK_PCIEX4_CORE 8 +#define DP1000_CLK_PCIEX16_CORE 9 +#define DP1000_CLK_PCIE_AUX 10 +#define DP1000_CLK_UART0 11 +#define DP1000_CLK_UART1 12 +#define DP1000_CLK_UART2 13 +#define DP1000_CLK_UART3 14 +#define DP1000_CLK_I2C0 15 +#define DP1000_CLK_I2C1 16 +#define DP1000_CLK_I2C2 17 +#define DP1000_CLK_I2C3 18 +#define DP1000_CLK_SPI0 19 +#define DP1000_CLK_SPI1 20 + +#endif /* _DT_BINDINGS_CLOCK_ULTRARISC_DP1000_CLK_H */ --=20 2.34.1 From nobody Sat Jul 25 03:21:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 4166020B80B; Mon, 20 Jul 2026 00:38:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784507906; cv=none; b=NF5vLZh+aBLqsSdGxy3hrgHdMsvgQoXCVK1z850ADKLbtWb5ayqkA81rARdCarRdSTLqSGhX/TLYqz5ok9DhqP4lmfWQuekO8AkAOn8Lta6R1ACIZqXtdwIbVpDIIxAIJGVln6x5K53m3CtlqN/uSQx8FmpvqBC9JLQpUZfMDF4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784507906; c=relaxed/simple; bh=QzXnogsmJUDPPmHZhFk6iv+GgfgGNELzbVc/Uw19ico=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cuR/La8CKxpISvcy/U0piQRFFJZhGOxCMSZ82g94X0kydicK+w6uk5I0P2FJmwlJxUTxSrs1dZNlOAxY7fKH3bEQv7VFk9rvYiSgpxEZY+UNvEm8jD4Xz12UyLiBaXGQeAJ2isT6dR3+DOuFFeEtcvvfJd/sDZ8oUQ1YEnxDAN8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FPocnRVB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FPocnRVB" Received: by smtp.kernel.org (Postfix) with ESMTPS id D9D6FC2BCFB; Mon, 20 Jul 2026 00:38:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1784507905; bh=QzXnogsmJUDPPmHZhFk6iv+GgfgGNELzbVc/Uw19ico=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FPocnRVBfTySaKQ6LZuTkRokTVnaMxTsQL92/sO07PlcKKZtzky1vG+9d7hJwaLYj P69NwbgJ5fr4d1Ap6V0T0mImqoNUBNc1wsatdpM60CqLvzTTCcLA7CvHXHQU3yF65H 3HtgW4mcPwHsw6zyabKA4Q79zYzDEnXbHT3k+2+m8QoKq2/DcGfujQeyOlDHWBY/AU LQbndUxBDgHU/S3s7kL+/zatB7lKwurrXBWa0RvhYJQTnT1BtCbOKcOtgZ+zBqq8hq XZQmi/n2IZ9bH6Q6HLPswJhoLC6jG25DonH3FDBx5gyq2qPVfE78gciO8wszp+9FhU /jwPg0IoltktQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA8C9C44512; Mon, 20 Jul 2026 00:38:25 +0000 (UTC) From: Jia Wang via B4 Relay Date: Mon, 20 Jul 2026 08:38:06 +0800 Subject: [PATCH v4 3/3] clk: ultrarisc: Add DP1000 clock driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260720-ultrarisc-clock-v4-3-fe639d63bbac@ultrarisc.com> References: <20260720-ultrarisc-clock-v4-0-fe639d63bbac@ultrarisc.com> In-Reply-To: <20260720-ultrarisc-clock-v4-0-fe639d63bbac@ultrarisc.com> To: Michael Turquette , Stephen Boyd , Brian Masney , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jia Wang X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784507902; l=21628; i=wangjia@ultrarisc.com; s=20260515; h=from:subject:message-id; bh=RsuveeDH0OrSqn+BMfKFeaup9uyqwAoepSytlv+EnAw=; b=WGvTeMAfW+lyHMD+15gw9H2dVHgpDpUrUDQmNRmljL3I1lhdK6bwLQQ+V///1uSRLutgI7jjF 9aDUEWYejKYDWENwL+FdtxFP7/7OYDnLwjJVeRHrLzNzqKqbMtFULiG X-Developer-Key: i=wangjia@ultrarisc.com; a=ed25519; pk=wGVm18siRScehKOkOz0WKxgxDy7IezHEszhnN4/TUCY= X-Endpoint-Received: by B4 Relay for wangjia@ultrarisc.com/20260515 with auth_id=779 X-Original-From: Jia Wang Reply-To: wangjia@ultrarisc.com From: Jia Wang Add a clock driver for the UltraRISC DP1000 SoC. The clock tree is driven by a SYSPLL and provides fixed-factor clocks for the subsystem and PCIe, divider-based root clocks for GMAC and the UART, I2C, and SPI blocks, and per-instance gate clocks for UART0-3, I2C0-3, and SPI0-1. Signed-off-by: Jia Wang Reviewed-by: Brian Masney --- MAINTAINERS | 1 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/ultrarisc/Kconfig | 18 ++ drivers/clk/ultrarisc/Makefile | 4 + drivers/clk/ultrarisc/clk-dp1000.c | 154 +++++++++++++ drivers/clk/ultrarisc/clk-ultrarisc.c | 399 ++++++++++++++++++++++++++++++= ++++ drivers/clk/ultrarisc/clk-ultrarisc.h | 71 ++++++ 8 files changed, 649 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d646707bb17f..d9a20d5ba13b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -27676,6 +27676,7 @@ M: Jia Wang L: linux-clk@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml +F: drivers/clk/ultrarisc/* F: include/dt-bindings/clock/ultrarisc,dp1000-clk.h =20 ULTRARISC DP1000 PINCTRL DRIVER diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 1717ce75a907..b33a0d93d909 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -541,6 +541,7 @@ source "drivers/clk/tenstorrent/Kconfig" source "drivers/clk/thead/Kconfig" source "drivers/clk/stm32/Kconfig" source "drivers/clk/ti/Kconfig" +source "drivers/clk/ultrarisc/Kconfig" source "drivers/clk/uniphier/Kconfig" source "drivers/clk/visconti/Kconfig" source "drivers/clk/x86/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index cc108a75a900..c66621a8b6cd 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -159,6 +159,7 @@ obj-$(CONFIG_ARCH_TEGRA) +=3D tegra/ obj-y +=3D tenstorrent/ obj-$(CONFIG_ARCH_THEAD) +=3D thead/ obj-y +=3D ti/ +obj-y +=3D ultrarisc/ obj-$(CONFIG_CLK_UNIPHIER) +=3D uniphier/ obj-$(CONFIG_ARCH_U8500) +=3D ux500/ obj-y +=3D versatile/ diff --git a/drivers/clk/ultrarisc/Kconfig b/drivers/clk/ultrarisc/Kconfig new file mode 100644 index 000000000000..2eecc6ac3119 --- /dev/null +++ b/drivers/clk/ultrarisc/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config CLK_ULTRARISC + tristate + depends on OF + depends on ARCH_ULTRARISC || COMPILE_TEST + +config CLK_ULTRARISC_DP1000 + tristate "UltraRISC DP1000 clock controller" + select CLK_ULTRARISC + depends on OF && HAS_IOMEM + depends on ARCH_ULTRARISC || COMPILE_TEST + default ARCH_ULTRARISC + help + This driver provides the clock controller for the UltraRISC + DP1000 SoC. It exposes the PLL output, derived fixed-factor + clocks, programmable divider clocks, and peripheral gate + clocks to Linux consumers. diff --git a/drivers/clk/ultrarisc/Makefile b/drivers/clk/ultrarisc/Makefile new file mode 100644 index 000000000000..b013708c9444 --- /dev/null +++ b/drivers/clk/ultrarisc/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_CLK_ULTRARISC) +=3D clk-ultrarisc.o +obj-$(CONFIG_CLK_ULTRARISC_DP1000) +=3D clk-dp1000.o diff --git a/drivers/clk/ultrarisc/clk-dp1000.c b/drivers/clk/ultrarisc/clk= -dp1000.c new file mode 100644 index 000000000000..ffea77c4cca0 --- /dev/null +++ b/drivers/clk/ultrarisc/clk-dp1000.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd. + */ + +#include + +#include + +#include "clk-ultrarisc.h" + +#define DP1000_PLL_CFG1_OFFSET 0x400 +#define DP1000_PLL_CFG2_OFFSET 0x404 + +#define DP1000_CCR_UART_OFFSET 0x220 +#define DP1000_CCR_I2C_OFFSET 0x224 +#define DP1000_CCR_GMAC_OFFSET 0x228 +#define DP1000_CCR_SPI_OFFSET 0x22c +#define DP1000_PERI_CLKENA_OFFSET 0x270 + +#define DP1000_CCR_LOAD BIT(16) + +#define DP1000_PERI_MAX_RATE 62500000UL +#define DP1000_CLK_NUM 21 + +static const struct ultrarisc_pll_layout dp1000_pll_layout =3D { + .cfg1_offset =3D DP1000_PLL_CFG1_OFFSET, + .cfg2_offset =3D DP1000_PLL_CFG2_OFFSET, + .frac_mask =3D GENMASK(23, 0), + .m_mask =3D GENMASK(23, 16), + .n_mask =3D GENMASK(11, 6), + .oddiv1_mask =3D GENMASK(1, 0), + .oddiv2_mask =3D GENMASK(4, 3), +}; + +static const struct ultrarisc_pll_desc dp1000_plls[] =3D { + { + .id =3D DP1000_CLK_SYSPLL, + .name =3D "syspll_clk", + }, +}; + +#define DP1000_FIXED_FACTOR(_id, _name, _parent, _mult, _div) \ + { \ + .id =3D (_id), \ + .name =3D (_name), \ + .parent_id =3D (_parent), \ + .mult =3D (_mult), \ + .div =3D (_div), \ + } + +#define DP1000_DIV(_id, _name, _offset, _parent, _max_rate) \ + { \ + .id =3D (_id), \ + .name =3D (_name), \ + .offset =3D (_offset), \ + .parent_id =3D (_parent), \ + .max_rate =3D (_max_rate), \ + .load_mask =3D DP1000_CCR_LOAD, \ + .div_shift =3D 8, \ + .div_width =3D 4, \ + .gate_bit =3D 0, \ + .divider_flags =3D CLK_DIVIDER_ONE_BASED, \ + .gate_flags =3D 0, \ + } + +#define DP1000_GATE(_id, _name, _parent, _bit) \ + { \ + .id =3D (_id), \ + .name =3D (_name), \ + .offset =3D DP1000_PERI_CLKENA_OFFSET, \ + .parent_id =3D (_parent), \ + .gate_bit =3D (_bit), \ + .gate_flags =3D 0, \ + } + +static const struct ultrarisc_fixed_factor_desc dp1000_fixed_factor_clks[]= =3D { + DP1000_FIXED_FACTOR(DP1000_CLK_SYSPLL_DIV2, "syspll_div2_clk", + DP1000_CLK_SYSPLL, 1, 2), + DP1000_FIXED_FACTOR(DP1000_CLK_SUBSYS, "subsys_clk", + DP1000_CLK_SYSPLL_DIV2, 1, 2), + DP1000_FIXED_FACTOR(DP1000_CLK_PCIE_DBI, "pcie_dbi_clk", + DP1000_CLK_SYSPLL, 1, 10), + DP1000_FIXED_FACTOR(DP1000_CLK_PCIEX4_CORE, "pciex4_core_clk", + DP1000_CLK_SYSPLL, 1, 2), + DP1000_FIXED_FACTOR(DP1000_CLK_PCIEX16_CORE, "pciex16_core_clk", + DP1000_CLK_SYSPLL, 1, 1), + DP1000_FIXED_FACTOR(DP1000_CLK_PCIE_AUX, "pcie_aux_clk", + DP1000_CLK_SYSPLL, 1, 40), +}; + +static const struct ultrarisc_divider_desc dp1000_divider_clks[] =3D { + DP1000_DIV(DP1000_CLK_GMAC, "gmac_clk", DP1000_CCR_GMAC_OFFSET, + DP1000_CLK_SYSPLL_DIV2, 0), + DP1000_DIV(DP1000_CLK_UART_ROOT, "uart_root_clk", + DP1000_CCR_UART_OFFSET, DP1000_CLK_SUBSYS, + DP1000_PERI_MAX_RATE), + DP1000_DIV(DP1000_CLK_I2C_ROOT, "i2c_root_clk", + DP1000_CCR_I2C_OFFSET, DP1000_CLK_SUBSYS, + DP1000_PERI_MAX_RATE), + DP1000_DIV(DP1000_CLK_SPI_ROOT, "spi_root_clk", + DP1000_CCR_SPI_OFFSET, DP1000_CLK_SUBSYS, + DP1000_PERI_MAX_RATE), +}; + +static const struct ultrarisc_gate_desc dp1000_gate_clks[] =3D { + DP1000_GATE(DP1000_CLK_UART0, "uart0_clk", DP1000_CLK_UART_ROOT, 0), + DP1000_GATE(DP1000_CLK_UART1, "uart1_clk", DP1000_CLK_UART_ROOT, 1), + DP1000_GATE(DP1000_CLK_UART2, "uart2_clk", DP1000_CLK_UART_ROOT, 2), + DP1000_GATE(DP1000_CLK_UART3, "uart3_clk", DP1000_CLK_UART_ROOT, 3), + DP1000_GATE(DP1000_CLK_I2C0, "i2c0_clk", DP1000_CLK_I2C_ROOT, 4), + DP1000_GATE(DP1000_CLK_I2C1, "i2c1_clk", DP1000_CLK_I2C_ROOT, 5), + DP1000_GATE(DP1000_CLK_I2C2, "i2c2_clk", DP1000_CLK_I2C_ROOT, 6), + DP1000_GATE(DP1000_CLK_I2C3, "i2c3_clk", DP1000_CLK_I2C_ROOT, 7), + DP1000_GATE(DP1000_CLK_SPI0, "spi0_clk", DP1000_CLK_SPI_ROOT, 8), + DP1000_GATE(DP1000_CLK_SPI1, "spi1_clk", DP1000_CLK_SPI_ROOT, 9), +}; + +static const struct ultrarisc_clk_soc_data dp1000_clk_soc_data =3D { + .num_clks =3D DP1000_CLK_NUM, + .pll_layout =3D &dp1000_pll_layout, + .plls =3D dp1000_plls, + .num_plls =3D ARRAY_SIZE(dp1000_plls), + .fixed_factors =3D dp1000_fixed_factor_clks, + .num_fixed_factors =3D ARRAY_SIZE(dp1000_fixed_factor_clks), + .dividers =3D dp1000_divider_clks, + .num_dividers =3D ARRAY_SIZE(dp1000_divider_clks), + .gates =3D dp1000_gate_clks, + .num_gates =3D ARRAY_SIZE(dp1000_gate_clks), +}; + +static int dp1000_clk_probe(struct platform_device *pdev) +{ + return ultrarisc_clk_probe(pdev, &dp1000_clk_soc_data); +} + +static const struct of_device_id dp1000_clk_of_match[] =3D { + { .compatible =3D "ultrarisc,dp1000-clk" }, + { } +}; +MODULE_DEVICE_TABLE(of, dp1000_clk_of_match); + +static struct platform_driver dp1000_clk_driver =3D { + .probe =3D dp1000_clk_probe, + .driver =3D { + .name =3D "ultrarisc-dp1000-clk", + .of_match_table =3D dp1000_clk_of_match, + }, +}; +module_platform_driver(dp1000_clk_driver); + +MODULE_IMPORT_NS("CLK_ULTRARISC"); +MODULE_DESCRIPTION("UltraRISC DP1000 clock controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/ultrarisc/clk-ultrarisc.c b/drivers/clk/ultrarisc/= clk-ultrarisc.c new file mode 100644 index 000000000000..bbcd2234ea71 --- /dev/null +++ b/drivers/clk/ultrarisc/clk-ultrarisc.c @@ -0,0 +1,399 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-ultrarisc.h" + +struct ultrarisc_pll_clk { + struct clk_hw hw; + void __iomem *base; + const struct ultrarisc_pll_layout *layout; +}; + +struct ultrarisc_divider_clk { + struct clk_divider divider; + struct clk_gate gate; + u32 load_mask; +}; + +#define to_ultrarisc_pll_clk(_hw) \ + container_of(_hw, struct ultrarisc_pll_clk, hw) + +static inline struct ultrarisc_divider_clk *to_ultrarisc_divider_clk(struc= t clk_hw *hw) +{ + struct clk_divider *divider =3D to_clk_divider(hw); + + return container_of(divider, struct ultrarisc_divider_clk, divider); +} + +static unsigned long ultrarisc_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ultrarisc_pll_clk *pll =3D to_ultrarisc_pll_clk(hw); + const struct ultrarisc_pll_layout *layout =3D pll->layout; + u32 oddiv1_div, oddiv2_div; + u64 mult, rate, den; + u32 frac, m, n; + u32 cfg1, cfg2; + + cfg1 =3D readl_relaxed(pll->base + layout->cfg1_offset); + cfg2 =3D readl_relaxed(pll->base + layout->cfg2_offset); + + frac =3D field_get(layout->frac_mask, cfg1); + m =3D field_get(layout->m_mask, cfg2); + n =3D field_get(layout->n_mask, cfg2); + if (!n) + return 0; + + oddiv1_div =3D 1U << field_get(layout->oddiv1_mask, cfg2); + oddiv2_div =3D 1U << field_get(layout->oddiv2_mask, cfg2); + + /* + * The output frequency is calculated as: + * fvco =3D parent * (m + frac / 2^24) / n + * fout =3D fvco / (2^oddiv1_raw * 2^oddiv2_raw) + * + * The output divider values are derived from the raw register field valu= es as: + * oddivX_div =3D 1 << oddivX_raw + */ + mult =3D ((u64)m << 24) + frac; + rate =3D (u64)parent_rate * mult; + den =3D ((u64)n << 24) * oddiv1_div * oddiv2_div; + + return div64_u64(rate + (den >> 1), den); +} + +static const struct clk_ops ultrarisc_pll_ro_ops =3D { + .recalc_rate =3D ultrarisc_pll_recalc_rate, +}; + +static unsigned long ultrarisc_divider_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_divider *divider =3D to_clk_divider(hw); + u32 val; + + val =3D readl_relaxed(divider->reg) >> divider->shift; + val &=3D clk_div_mask(divider->width); + + return divider_recalc_rate(hw, parent_rate, val, divider->table, + divider->flags, divider->width); +} + +static int ultrarisc_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_divider *divider =3D to_clk_divider(hw); + + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); +} + +static int ultrarisc_divider_set_rate(struct clk_hw *hw, unsigned long rat= e, + unsigned long parent_rate) +{ + struct ultrarisc_divider_clk *divider_clk =3D to_ultrarisc_divider_clk(hw= ); + struct clk_divider *divider =3D ÷r_clk->divider; + int value; + u32 val; + + value =3D divider_get_val(rate, parent_rate, divider->table, + divider->width, divider->flags); + if (value < 0) + return value; + + scoped_guard(spinlock_irqsave, divider->lock) { + val =3D readl_relaxed(divider->reg); + val &=3D ~(clk_div_mask(divider->width) << divider->shift); + val |=3D value << divider->shift; + writel_relaxed(val, divider->reg); + + if (divider_clk->load_mask) { + /* + * Program the new divider field, then write 1 to the + * load bit to trigger the update. The load bit is + * write-triggered and reads back as 0 on this hardware. + */ + writel_relaxed(val | divider_clk->load_mask, divider->reg); + } + } + + return 0; +} + +static const struct clk_ops ultrarisc_divider_ops =3D { + .recalc_rate =3D ultrarisc_divider_recalc_rate, + .determine_rate =3D ultrarisc_divider_determine_rate, + .set_rate =3D ultrarisc_divider_set_rate, +}; + +static struct clk_hw *ultrarisc_clk_register_pll(struct device *dev, + const struct ultrarisc_pll_desc *desc, + const struct ultrarisc_pll_layout *layout, + void __iomem *base) +{ + struct clk_parent_data pdata =3D { .index =3D 0 }; + struct ultrarisc_pll_clk *pll; + struct clk_init_data init =3D { + .name =3D desc->name, + .ops =3D &ultrarisc_pll_ro_ops, + .parent_data =3D &pdata, + .num_parents =3D 1, + .flags =3D CLK_GET_RATE_NOCACHE, + }; + int ret; + + pll =3D devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + pll->base =3D base; + pll->layout =3D layout; + pll->hw.init =3D &init; + + ret =3D devm_clk_hw_register(dev, &pll->hw); + if (ret) + return ERR_PTR(ret); + + return &pll->hw; +} + +static struct clk_hw * +ultrarisc_clk_register_divider(struct device *dev, + const struct ultrarisc_divider_desc *desc, + struct clk_hw *parent_hw, void __iomem *base, + spinlock_t *lock) +{ + const struct clk_parent_data pdata =3D { .hw =3D parent_hw }; + void __iomem *reg =3D base + desc->offset; + struct ultrarisc_divider_clk *divider; + + if (!desc->div_width) + return ERR_PTR(-EINVAL); + + if (!lock) + return ERR_PTR(-EINVAL); + + divider =3D devm_kzalloc(dev, sizeof(*divider), GFP_KERNEL); + if (!divider) + return ERR_PTR(-ENOMEM); + + divider->divider.reg =3D reg; + divider->divider.shift =3D desc->div_shift; + divider->divider.width =3D desc->div_width; + divider->divider.flags =3D desc->divider_flags; + divider->divider.lock =3D lock; + divider->load_mask =3D desc->load_mask; + divider->gate.reg =3D reg; + divider->gate.bit_idx =3D desc->gate_bit; + divider->gate.flags =3D desc->gate_flags; + divider->gate.lock =3D lock; + + return devm_clk_hw_register_composite_pdata(dev, desc->name, + &pdata, 1, NULL, NULL, + ÷r->divider.hw, + &ultrarisc_divider_ops, + ÷r->gate.hw, + &clk_gate_ops, 0); +} + +static int ultrarisc_clk_register_fixed_factors(struct device *dev, + struct clk_hw_onecell_data *clk_data, + const struct ultrarisc_clk_soc_data *soc_data) +{ + u32 i; + + for (i =3D 0; i < soc_data->num_fixed_factors; i++) { + const struct ultrarisc_fixed_factor_desc *desc; + struct clk_hw *parent_hw; + struct clk_hw *hw; + + desc =3D &soc_data->fixed_factors[i]; + if (desc->id >=3D clk_data->num || desc->parent_id >=3D clk_data->num) + return -EINVAL; + + parent_hw =3D clk_data->hws[desc->parent_id]; + if (!parent_hw) + return -EINVAL; + + hw =3D devm_clk_hw_register_fixed_factor_parent_hw(dev, desc->name, + parent_hw, 0, + desc->mult, + desc->div); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + clk_data->hws[desc->id] =3D hw; + } + + return 0; +} + +static int ultrarisc_clk_register_plls(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data, + const struct ultrarisc_clk_soc_data *soc_data, + void __iomem *base) +{ + struct device *dev =3D &pdev->dev; + u32 i; + + for (i =3D 0; i < soc_data->num_plls; i++) { + const struct ultrarisc_pll_desc *desc =3D &soc_data->plls[i]; + struct clk_hw *hw; + + if (desc->id >=3D clk_data->num) { + dev_err(dev, "%s invalid clock ID %u >=3D %u\n", + desc->name, desc->id, clk_data->num); + return -EINVAL; + } + + hw =3D ultrarisc_clk_register_pll(dev, desc, soc_data->pll_layout, base); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + clk_data->hws[desc->id] =3D hw; + } + + return 0; +} + +static int ultrarisc_clk_register_dividers(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data, + const struct ultrarisc_clk_soc_data *soc_data, + void __iomem *base, + spinlock_t *lock) +{ + struct device *dev =3D &pdev->dev; + u32 i; + + for (i =3D 0; i < soc_data->num_dividers; i++) { + const struct ultrarisc_divider_desc *desc; + struct clk_hw *parent_hw; + struct clk_hw *hw; + + desc =3D &soc_data->dividers[i]; + if (desc->id >=3D clk_data->num || desc->parent_id >=3D clk_data->num) + return -EINVAL; + + parent_hw =3D clk_data->hws[desc->parent_id]; + if (!parent_hw) + return -EINVAL; + + hw =3D ultrarisc_clk_register_divider(dev, desc, parent_hw, base, + lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + if (desc->max_rate) + clk_hw_set_rate_range(hw, 0, desc->max_rate); + + clk_data->hws[desc->id] =3D hw; + } + + return 0; +} + +static int ultrarisc_clk_register_gates(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data, + const struct ultrarisc_clk_soc_data *soc_data, + void __iomem *base, + spinlock_t *lock) +{ + struct device *dev =3D &pdev->dev; + u32 i; + + for (i =3D 0; i < soc_data->num_gates; i++) { + const struct ultrarisc_gate_desc *desc; + struct clk_hw *parent_hw; + struct clk_hw *hw; + + desc =3D &soc_data->gates[i]; + if (desc->id >=3D clk_data->num || desc->parent_id >=3D clk_data->num) + return -EINVAL; + + parent_hw =3D clk_data->hws[desc->parent_id]; + if (!parent_hw) + return -EINVAL; + + hw =3D devm_clk_hw_register_gate_parent_hw(dev, desc->name, + parent_hw, 0, + base + desc->offset, + desc->gate_bit, + desc->gate_flags, + lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + clk_data->hws[desc->id] =3D hw; + } + + return 0; +} + +int ultrarisc_clk_probe(struct platform_device *pdev, + const struct ultrarisc_clk_soc_data *soc_data) +{ + struct clk_hw_onecell_data *clk_data; + struct device *dev =3D &pdev->dev; + void __iomem *base; + spinlock_t *lock; + int ret; + + if (!soc_data) + return -EINVAL; + + lock =3D devm_kzalloc(dev, sizeof(*lock), GFP_KERNEL); + if (!lock) + return -ENOMEM; + + spin_lock_init(lock); + + clk_data =3D devm_kzalloc(dev, struct_size(clk_data, hws, + soc_data->num_clks), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->num =3D soc_data->num_clks; + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + ret =3D ultrarisc_clk_register_plls(pdev, clk_data, soc_data, base); + if (ret) + return ret; + + ret =3D ultrarisc_clk_register_fixed_factors(dev, clk_data, soc_data); + if (ret) + return ret; + + ret =3D ultrarisc_clk_register_dividers(pdev, clk_data, soc_data, base, l= ock); + if (ret) + return ret; + + ret =3D ultrarisc_clk_register_gates(pdev, clk_data, soc_data, base, lock= ); + if (ret) + return ret; + + for (int i =3D 0; i < clk_data->num; i++) { + if (!clk_data->hws[i]) { + dev_err(dev, "missing clock ID %u\n", i); + return -EINVAL; + } + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); +} +EXPORT_SYMBOL_NS_GPL(ultrarisc_clk_probe, "CLK_ULTRARISC"); + +MODULE_DESCRIPTION("UltraRISC clock core driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/ultrarisc/clk-ultrarisc.h b/drivers/clk/ultrarisc/= clk-ultrarisc.h new file mode 100644 index 000000000000..8202b7ed0e31 --- /dev/null +++ b/drivers/clk/ultrarisc/clk-ultrarisc.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ULTRARISC_CLK_ULTRARISC_H +#define __ULTRARISC_CLK_ULTRARISC_H + +#include +#include +#include + +struct ultrarisc_pll_layout { + u32 cfg1_offset; + u32 cfg2_offset; + u32 frac_mask; + u32 m_mask; + u32 n_mask; + u32 oddiv1_mask; + u32 oddiv2_mask; +}; + +struct ultrarisc_pll_desc { + u32 id; + const char *name; +}; + +struct ultrarisc_fixed_factor_desc { + u32 id; + const char *name; + u32 parent_id; + u32 mult; + u32 div; +}; + +struct ultrarisc_divider_desc { + u32 id; + const char *name; + u32 offset; + u32 parent_id; + unsigned long max_rate; + u32 load_mask; + u8 div_shift; + u8 div_width; + u8 gate_bit; + u16 divider_flags; + u8 gate_flags; +}; + +struct ultrarisc_gate_desc { + u32 id; + const char *name; + u32 offset; + u32 parent_id; + u8 gate_bit; + u8 gate_flags; +}; + +struct ultrarisc_clk_soc_data { + const struct ultrarisc_pll_layout *pll_layout; + const struct ultrarisc_pll_desc *plls; + u32 num_plls; + const struct ultrarisc_fixed_factor_desc *fixed_factors; + u32 num_fixed_factors; + const struct ultrarisc_divider_desc *dividers; + u32 num_dividers; + const struct ultrarisc_gate_desc *gates; + u32 num_gates; + u32 num_clks; +}; + +int ultrarisc_clk_probe(struct platform_device *pdev, + const struct ultrarisc_clk_soc_data *soc_data); + +#endif /* __ULTRARISC_CLK_ULTRARISC_H */ --=20 2.34.1