From nobody Sat Jul 25 20:49:05 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 20F6B360EC4; Tue, 14 Jul 2026 01:35:09 +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=1783992910; cv=none; b=ARvjWeJEDjpvPmTShSPsHtxCTlHyATsR9k2CbeJLjd2YkVdbvXDs7Zr1t9e/lQJ0OkfrpQuH8eR+reb1RiuYgob2I0HXQ2TRSvCRbI/Mko3Nvd+7aLSKO+ZMHXxmWsAplnaQ4T7AZC0bP6BkHbLUeTf4ppvDyhJiO905cM3o95U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783992910; c=relaxed/simple; bh=i+vNWFu0WMNpWI91QVE2Zdt4dVaM7AXfu0XL56oslRc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=h8byqT+0tUO0/95FIINtkx3QIgho+7GOpd4owZpK/TLrfEHaIaeAPEOlKgdQXV0z1q5b4DqntAinx+wZFqYovo/18ZnaHjCEjYsH8TN5kuIQfCmGbW2lhL3NmUzkIRCljV7iMoFgnyrbHfR6MCrTECXOl8LzQCwaGR+K54WxiLk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=l9EhaJ3Z; 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="l9EhaJ3Z" Received: by smtp.kernel.org (Postfix) with ESMTPS id BA7DEC2BCB9; Tue, 14 Jul 2026 01:35:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783992909; bh=i+vNWFu0WMNpWI91QVE2Zdt4dVaM7AXfu0XL56oslRc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=l9EhaJ3ZwQo6rzj4WepxsnmgXPrtzzQBTplNoY4ECz1+SRyg1maLKqYe4kJjHPhnt cLw9DGKuntK2lNxyr6BgPdZBZDplIkhv84AQyw9ZI8EaKPR1RZDlRyKphLExjLqk8c AhFOR8APl2RqXJzMMXmKcHHzAF+epgxdLT+5CkzAyfwx2xJrNtv7YM2UEqqgKGf0J1 4mU4PgGPz6sqeaA+ntSbeJl4xwgz2x0f/jYLwxiw8asBKBQ/8exV0ycumDDmA8gBD9 QcYk46w4sm8qeW2ok6so/8vNqW6rvPdW2/YizrmuD5hRValaVJY9GqfvFN2OknObO3 FvK6VhYKNBXlw== 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 9C492C44501; Tue, 14 Jul 2026 01:35:09 +0000 (UTC) From: Jia Wang via B4 Relay Date: Tue, 14 Jul 2026 09:35:07 +0800 Subject: [PATCH v3 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: <20260714-ultrarisc-clock-v3-1-4b1ccaa26b37@ultrarisc.com> References: <20260714-ultrarisc-clock-v3-0-4b1ccaa26b37@ultrarisc.com> In-Reply-To: <20260714-ultrarisc-clock-v3-0-4b1ccaa26b37@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=1783992908; l=797; i=wangjia@ultrarisc.com; s=20260515; h=from:subject:message-id; bh=8T/bzSyCQgQUdtW8jZQCk07FkbCd8+9jHeSg8tcJ/w4=; b=I66Zq+FmxIu0b3yH8s5tk9YjFDzCEY2GPNmcpVat1RMClR8P7hb4dRbNGPsT7RIjF3vrdGAHC /fkb2AITbfCDwgyJ5ikrnate2AnNcqyJH4uyMj9S0Xvwbh6akWkpWyR 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 20:49:05 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 20EF135F60E; Tue, 14 Jul 2026 01:35:10 +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=1783992910; cv=none; b=ZqxoUq1+wfMp+kspDwJLCHQgM+Qlm0gKQA6w4s6qL3wnq4EPNW18k4IciTbxdKGhPNuEjSzXWPXlrC4LvAR68/gH1QqyCya39ng+7OUfALgHQHnjvAYdC9Cear8FOPOvjoCXr660V789fcR8H//svNYv0qjybQ21Xanpv+EfxtM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783992910; c=relaxed/simple; bh=ndlFAPnsB0Fq6i2L0rhg60nuodlsSu9z7E3c34glIHY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RB8KRpkSEMsOgpAWMcpdUQxfJEpIUlUqiVm7/+BH/yc5t/OymaaebZPazZtNaj/TW6c4ktXStchJwZ13ojKAZMyAXvo7oS5OqCYvNiJ1Tf59HP+xyCxazvE2WXXOhqIRkgsbbRGi/KGXsVc2YCGJFTPr9AAixeZipnMjPn1tMfc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=goXFN69t; 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="goXFN69t" Received: by smtp.kernel.org (Postfix) with ESMTPS id C6FC7C2BCF5; Tue, 14 Jul 2026 01:35:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783992909; bh=ndlFAPnsB0Fq6i2L0rhg60nuodlsSu9z7E3c34glIHY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=goXFN69tZfC1JeCcE6kHSIaSMoHn6FzOrZWEw+cr9IMMKBa8MsFvHaioimx2L6MQR N6KYCLap11eocXBuhMBpNGQi0ZSvTZ8cKFE3NfBrOTi6my4UA27f7egsaiykDzenxm qesfojp1JvpD7rEwCcen9/l55dXcryyIJYnNVblh0AtQd3y3JaumCvzc69j/HAMgrX JSfunSauYbraMzdeI48tadqeavZSi7oIqXwfYs4rn6ucAVAFQ8KRO/qziau7Emj73Y WagjnwpF8gzUOlnPv5g5pBXXWRRpGYfGMQUg9ptqqbLRHW2ncerrxSOagi+D8OBeym TzMpL0Q7QXU2g== 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 A97C6C44508; Tue, 14 Jul 2026 01:35:09 +0000 (UTC) From: Jia Wang via B4 Relay Date: Tue, 14 Jul 2026 09:35:08 +0800 Subject: [PATCH v3 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: <20260714-ultrarisc-clock-v3-2-4b1ccaa26b37@ultrarisc.com> References: <20260714-ultrarisc-clock-v3-0-4b1ccaa26b37@ultrarisc.com> In-Reply-To: <20260714-ultrarisc-clock-v3-0-4b1ccaa26b37@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=1783992908; l=4082; i=wangjia@ultrarisc.com; s=20260515; h=from:subject:message-id; bh=hAYITNry4LyDjLKPqs+Vj2CAziH/un6ry4g7V+jxfJw=; b=M3WkSIcreWFF8Dnzm6cgfgu0rPe0JYKA5S+JOmNwQfaD5gsCBm0wMu0ycMSDfnflh5Bl+JKAt wvnSshtjZV0Dfy5dxd1CTWRNV7fDbyaYwAuevh4uW+rl+S8Ajzeo4cc 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 20:49:05 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 20DEA35DA75; Tue, 14 Jul 2026 01:35:10 +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=1783992910; cv=none; b=rm4hqIPiESQLUPaRR/aeU8GbkvwOwZf/ZkuIwgYSVimDgyJ3gERSz3+M59DOqgE+sMbJf2GMSpSalp9rSMb+9VloJk9fL7MqDcjVG7p2HOhGiB/g/Y3ksYDy4lfYm2ZiOxDI9QIOihuYIWdRgtAj717kK6EUwFNYYkQO4PXQfas= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783992910; c=relaxed/simple; bh=F26QaJx9sl604URtwE6JAh1iCYOPqnVEQw2Yhx4xxU8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=T0dhtUcH8UAWRNfeEvkfKLb/r0vu9Y2i1JmSiA1pvfzizXgMcMYCZsOEipMImf2y5ttFxRMTYNMLoESiB8JVhBDv6ASJqQBfTbbrRslQIRRuJPVY6ERtsC8zpE0MEEViIBQZWG/07Y7T69lLIGcKvlarOhyWJbmgidJJpppIe04= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fox3kMx0; 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="fox3kMx0" Received: by smtp.kernel.org (Postfix) with ESMTPS id D399DC2BCF7; Tue, 14 Jul 2026 01:35:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783992909; bh=F26QaJx9sl604URtwE6JAh1iCYOPqnVEQw2Yhx4xxU8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=fox3kMx0g8+EZQPsSNppA9B8MxlAqtYMsGWtuy7UnN5ZThKHQJ0sOmtF2zuU1zzLE LuDmg0DuBhCIzcUFDEsjnn25+rFsDiJh/GGAT9+wFHmUf53v1Q6aJZN6pFAMlDvHON OiXheGIv6C92IphbxXESBEFhftHG58XiWZCApHscqJsZZkH2lIrMFKztYnzdADdD10 Pcoscw6Mc9SlGGHF9jxPt24Qvl/tsk70aPQZkws2SYk2BnSJh5dpvy7wpi9S/yWp9T p2yz+kYDngdiKjy0Ndnrkxxwzk+s+WTgX0PtwRXPsp2+L25TyKJ3LrHNmgyI2Fc16v 02DVRv6gICz2w== 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 B875BC44507; Tue, 14 Jul 2026 01:35:09 +0000 (UTC) From: Jia Wang via B4 Relay Date: Tue, 14 Jul 2026 09:35:09 +0800 Subject: [PATCH v3 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: <20260714-ultrarisc-clock-v3-3-4b1ccaa26b37@ultrarisc.com> References: <20260714-ultrarisc-clock-v3-0-4b1ccaa26b37@ultrarisc.com> In-Reply-To: <20260714-ultrarisc-clock-v3-0-4b1ccaa26b37@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=1783992908; l=21828; i=wangjia@ultrarisc.com; s=20260515; h=from:subject:message-id; bh=eCIu2c1M/VDIoTzeSIEnsQlfiMD1h3d09vd9jEEB2ks=; b=7DthACWDJjItLTJvYZEF9BhnIzD3yimHziu2fWynMyok2XXVfk2bOepzyTiAQxUXPZ0Bq5a35 bNzJ8ecdt8FBxKA59gEdzeTYw1R2GR52AqNnrYZMvCTr9Fl90S/TT8E 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 --- 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 | 407 ++++++++++++++++++++++++++++++= ++++ drivers/clk/ultrarisc/clk-ultrarisc.h | 71 ++++++ 8 files changed, 657 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..6e824a4f238e --- /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(4, 3), + .oddiv2_mask =3D GENMASK(1, 0), +}; + +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..f06ada5a9fe0 --- /dev/null +++ b/drivers/clk/ultrarisc/clk-ultrarisc.c @@ -0,0 +1,407 @@ +// 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) { + unsigned long rate; + + clk_hw_set_rate_range(hw, 0, desc->max_rate); + + rate =3D clk_hw_get_rate(hw); + if (rate > desc->max_rate) + dev_warn(dev, "%s rate %lu exceeds max %lu\n", + desc->name, rate, 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