From nobody Tue May 13 04:18:04 2025
Received: from bayard.4d2.org (bayard.4d2.org [155.254.16.17])
	(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 0008320E33F;
	Tue,  1 Apr 2025 17:24:54 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=155.254.16.17
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743528297; cv=none;
 b=jsQGEgePD6THgYPQaG51AIuS0stf2B3z6OwLJnjxhKr5HRVk3WTnpr7kLmvgMVZwa4pVS1sF3hY2HJTL3VdZ27tFtATn/mEEke7CjZmPTiOoMLIuYg296cpCJRZktKr5CNQJ7axkC/YyH0bcR1u240lEhGvQOW7RJBt/GZVEjRw=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743528297; c=relaxed/simple;
	bh=FeUiLSUe8wj7dt0M38twYoeyAWpif9rAC5K+gAkMce4=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=sbGMdJtdJQxgMEiQj6j7Kokkj2XeMYIpErWSpp7uKYFk3uuQckCsLp86Q7qvf/R/WbWiM4HRipPdOg329vEsu9Q7VYgFXK0eF7aU8EfvcrJ1zHMMlnby9xurKZPT8C+2oEriy7A3q/qWg8Ax8fkcfCd0kRGJLLWSPFITFiHJooQ=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org;
 spf=pass smtp.mailfrom=4d2.org;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=qtO9GA4/;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=lRRI8g8u; arc=none smtp.client-ip=155.254.16.17
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="qtO9GA4/";
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="lRRI8g8u"
Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1])
	by bayard.4d2.org (Postfix) with ESMTP id 5C0BDEC59FE;
	Tue, 01 Apr 2025 10:24:54 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528294; bh=FeUiLSUe8wj7dt0M38twYoeyAWpif9rAC5K+gAkMce4=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=qtO9GA4/5E/GAcM2hgUvUwhkJeO0X5Rd/V8uvVlvn0M6TtrP7AUv4gvb+lIF051g2
	 cmFKSS6mbhrvEGUXzH/zUb5bW0rtsDk2N+Qd/6r9xL6qOD9lKSfQNG8x9bFWgek4Bm
	 HuQ0YIcQOf8pT4s3GmESTkfeKDN0if0As5kMUsmkJbA2jXR7yrx+EXaEhEH4MrDEBy
	 fKWYx8SKKv4JlvG9zOuEYAa7r51gox92tULWX0wvwQukUijY5t4X9ti3DBZxynw5r/
	 ptSJAKvMfTvGeYGIR0QpN2xPzLcf2kw9ZQAZQxC3uLv0w5hna7Mfp2SpYB88DsCTS/
	 nuCLO1ACD/7IQ==
X-Virus-Scanned: amavisd-new at 4d2.org
Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key)
 header.d=4d2.org
Received: from bayard.4d2.org ([127.0.0.1])
 by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id BoZijOi-vwPz; Tue,  1 Apr 2025 10:24:51 -0700 (PDT)
Received: from localhost.localdomain (unknown [183.217.81.55])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange x25519 server-signature ECDSA (prime256v1) server-digest
 SHA256)
	(No client certificate requested)
	(Authenticated sender: heylenay@4d2.org)
	by bayard.4d2.org (Postfix) with ESMTPSA id F17B3EC59FC;
	Tue, 01 Apr 2025 10:24:46 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528291; bh=FeUiLSUe8wj7dt0M38twYoeyAWpif9rAC5K+gAkMce4=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=lRRI8g8uEhxV6S8aYl+sfGYNAVEBQP+koZjQuRpfB18lma2wX5TGWO5TC7DcF6sIl
	 zTirzk9m4XLm7zHXzkO+zgrfU2nD+9dYkmt787yBc37QkrUvddilO2RjazUvoSBh2r
	 o6sSa3TkjIbk2/iiocKPsx9HwrV9fZzEoToZpEqGpSQUbavyigJRphOO4Rtnv+IRJ4
	 V0HhLMSGHLIEAy7D2uaWdP6XmteI1/ZZlNrREPz67emyx7t3z59mChE20X6AUtocYb
	 TUGpPTHlgVCu4KiFINUbmiNUyjLvRB3q3vlWZHuHWEcnomTLQnaEOafqRvWzNFtXmh
	 w/lkv6cUk3kbg==
From: Haylen Chu <heylenay@4d2.org>
To: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Haylen Chu <heylenay@outlook.com>,
	Yixun Lan <dlan@gentoo.org>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>
Cc: linux-riscv@lists.infradead.org,
	linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	spacemit@lists.linux.dev,
	Inochi Amaoto <inochiama@outlook.com>,
	Chen Wang <unicornxdotw@foxmail.com>,
	Jisheng Zhang <jszhang@kernel.org>,
	Meng Zhang <zhangmeng.kevin@linux.spacemit.com>,
	Haylen Chu <heylenay@4d2.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Subject: [PATCH v6 1/6] dt-bindings: soc: spacemit: Add spacemit,k1-syscon
Date: Tue,  1 Apr 2025 17:24:29 +0000
Message-ID: <20250401172434.6774-2-heylenay@4d2.org>
X-Mailer: git-send-email 2.49.0
In-Reply-To: <20250401172434.6774-1-heylenay@4d2.org>
References: <20250401172434.6774-1-heylenay@4d2.org>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

Document APMU, MPMU and APBC syscons found on SpacemiT K1 SoC, which are
capable of generating clock and reset signals. Additionally, APMU and MPMU
manage power domains.

Signed-off-by: Haylen Chu <heylenay@4d2.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Alex Elder <riscstar.com>
---
 .../soc/spacemit/spacemit,k1-syscon.yaml      |  80 +++++++
 .../dt-bindings/clock/spacemit,k1-syscon.h    | 210 ++++++++++++++++++
 2 files changed, 290 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit=
,k1-syscon.yaml
 create mode 100644 include/dt-bindings/clock/spacemit,k1-syscon.h

diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-sys=
con.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-sysco=
n.yaml
new file mode 100644
index 000000000000..30aaf49da03d
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SpacemiT K1 SoC System Controller
+
+maintainers:
+  - Haylen Chu <heylenay@4d2.org>
+
+description:
+  System controllers found on SpacemiT K1 SoC, which are capable of
+  clock, reset and power-management functions.
+
+properties:
+  compatible:
+    enum:
+      - spacemit,k1-syscon-apbc
+      - spacemit,k1-syscon-apmu
+      - spacemit,k1-syscon-mpmu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 4
+
+  clock-names:
+    items:
+      - const: osc
+      - const: vctcxo_1m
+      - const: vctcxo_3m
+      - const: vctcxo_24m
+
+  "#clock-cells":
+    const: 1
+    description:
+      See <dt-bindings/clock/spacemit,k1-syscon.h> for valid indices.
+
+  "#power-domain-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - "#reset-cells"
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: spacemit,k1-syscon-apbc
+    then:
+      properties:
+        "#power-domain-cells": false
+    else:
+      required:
+        - "#power-domain-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    system-controller@d4050000 {
+        compatible =3D "spacemit,k1-syscon-mpmu";
+        reg =3D <0xd4050000 0x209c>;
+        clocks =3D <&osc>, <&vctcxo_1m>, <&vctcxo_3m>, <&vctcxo_24m>;
+        clock-names =3D "osc", "vctcxo_1m", "vctcxo_3m", "vctcxo_24m";
+        #clock-cells =3D <1>;
+        #power-domain-cells =3D <1>;
+        #reset-cells =3D <1>;
+    };
diff --git a/include/dt-bindings/clock/spacemit,k1-syscon.h b/include/dt-bi=
ndings/clock/spacemit,k1-syscon.h
new file mode 100644
index 000000000000..61c8d7360cf8
--- /dev/null
+++ b/include/dt-bindings/clock/spacemit,k1-syscon.h
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+
+#ifndef _DT_BINDINGS_SPACEMIT_CCU_H_
+#define _DT_BINDINGS_SPACEMIT_CCU_H_
+
+/* MPMU clocks */
+#define CLK_PLL1_307P2		0
+#define CLK_PLL1_76P8		1
+#define CLK_PLL1_61P44		2
+#define CLK_PLL1_153P6		3
+#define CLK_PLL1_102P4		4
+#define CLK_PLL1_51P2		5
+#define CLK_PLL1_51P2_AP	6
+#define CLK_PLL1_57P6		7
+#define CLK_PLL1_25P6		8
+#define CLK_PLL1_12P8		9
+#define CLK_PLL1_12P8_WDT	10
+#define CLK_PLL1_6P4		11
+#define CLK_PLL1_3P2		12
+#define CLK_PLL1_1P6		13
+#define CLK_PLL1_0P8		14
+#define CLK_PLL1_409P6		15
+#define CLK_PLL1_204P8		16
+#define CLK_PLL1_491		17
+#define CLK_PLL1_245P76		18
+#define CLK_PLL1_614		19
+#define CLK_PLL1_47P26		20
+#define CLK_PLL1_31P5		21
+#define CLK_PLL1_819		22
+#define CLK_PLL1_1228		23
+#define CLK_SLOW_UART		24
+#define CLK_SLOW_UART1		25
+#define CLK_SLOW_UART2		26
+#define CLK_WDT			27
+#define CLK_RIPC		28
+#define CLK_I2S_SYSCLK		29
+#define CLK_I2S_BCLK		30
+#define CLK_APB			31
+#define CLK_WDT_BUS		32
+
+/* APBC clocks */
+#define CLK_UART0		0
+#define CLK_UART2		1
+#define CLK_UART3		2
+#define CLK_UART4		3
+#define CLK_UART5		4
+#define CLK_UART6		5
+#define CLK_UART7		6
+#define CLK_UART8		7
+#define CLK_UART9		8
+#define CLK_GPIO		9
+#define CLK_PWM0		10
+#define CLK_PWM1		11
+#define CLK_PWM2		12
+#define CLK_PWM3		13
+#define CLK_PWM4		14
+#define CLK_PWM5		15
+#define CLK_PWM6		16
+#define CLK_PWM7		17
+#define CLK_PWM8		18
+#define CLK_PWM9		19
+#define CLK_PWM10		20
+#define CLK_PWM11		21
+#define CLK_PWM12		22
+#define CLK_PWM13		23
+#define CLK_PWM14		24
+#define CLK_PWM15		25
+#define CLK_PWM16		26
+#define CLK_PWM17		27
+#define CLK_PWM18		28
+#define CLK_PWM19		29
+#define CLK_SSP3		30
+#define CLK_RTC			31
+#define CLK_TWSI0		32
+#define CLK_TWSI1		33
+#define CLK_TWSI2		34
+#define CLK_TWSI4		35
+#define CLK_TWSI5		36
+#define CLK_TWSI6		37
+#define CLK_TWSI7		38
+#define CLK_TWSI8		39
+#define CLK_TIMERS1		40
+#define CLK_TIMERS2		41
+#define CLK_AIB			42
+#define CLK_ONEWIRE		43
+#define CLK_SSPA0		44
+#define CLK_SSPA1		45
+#define CLK_DRO			46
+#define CLK_IR			47
+#define CLK_TSEN		48
+#define CLK_IPC_AP2AUD		49
+#define CLK_CAN0		50
+#define CLK_CAN0_BUS		51
+#define CLK_UART0_BUS		52
+#define CLK_UART2_BUS		53
+#define CLK_UART3_BUS		54
+#define CLK_UART4_BUS		55
+#define CLK_UART5_BUS		56
+#define CLK_UART6_BUS		57
+#define CLK_UART7_BUS		58
+#define CLK_UART8_BUS		59
+#define CLK_UART9_BUS		60
+#define CLK_GPIO_BUS		61
+#define CLK_PWM0_BUS		62
+#define CLK_PWM1_BUS		63
+#define CLK_PWM2_BUS		64
+#define CLK_PWM3_BUS		65
+#define CLK_PWM4_BUS		66
+#define CLK_PWM5_BUS		67
+#define CLK_PWM6_BUS		68
+#define CLK_PWM7_BUS		69
+#define CLK_PWM8_BUS		70
+#define CLK_PWM9_BUS		71
+#define CLK_PWM10_BUS		72
+#define CLK_PWM11_BUS		73
+#define CLK_PWM12_BUS		74
+#define CLK_PWM13_BUS		75
+#define CLK_PWM14_BUS		76
+#define CLK_PWM15_BUS		77
+#define CLK_PWM16_BUS		78
+#define CLK_PWM17_BUS		79
+#define CLK_PWM18_BUS		80
+#define CLK_PWM19_BUS		81
+#define CLK_SSP3_BUS		82
+#define CLK_RTC_BUS		83
+#define CLK_TWSI0_BUS		84
+#define CLK_TWSI1_BUS		85
+#define CLK_TWSI2_BUS		86
+#define CLK_TWSI4_BUS		87
+#define CLK_TWSI5_BUS		88
+#define CLK_TWSI6_BUS		89
+#define CLK_TWSI7_BUS		90
+#define CLK_TWSI8_BUS		91
+#define CLK_TIMERS1_BUS		92
+#define CLK_TIMERS2_BUS		93
+#define CLK_AIB_BUS		94
+#define CLK_ONEWIRE_BUS		95
+#define CLK_SSPA0_BUS		96
+#define CLK_SSPA1_BUS		97
+#define CLK_TSEN_BUS		98
+#define CLK_IPC_AP2AUD_BUS	99
+
+/* APMU clocks */
+#define CLK_CCI550		0
+#define CLK_CPU_C0_HI		1
+#define CLK_CPU_C0_CORE		2
+#define CLK_CPU_C0_ACE		3
+#define CLK_CPU_C0_TCM		4
+#define CLK_CPU_C1_HI		5
+#define CLK_CPU_C1_CORE		6
+#define CLK_CPU_C1_ACE		7
+#define CLK_CCIC_4X		8
+#define CLK_CCIC1PHY		9
+#define CLK_SDH_AXI		10
+#define CLK_SDH0		11
+#define CLK_SDH1		12
+#define CLK_SDH2		13
+#define CLK_USB_P1		14
+#define CLK_USB_AXI		15
+#define CLK_USB30		16
+#define CLK_QSPI		17
+#define CLK_QSPI_BUS		18
+#define CLK_DMA			19
+#define CLK_AES			20
+#define CLK_VPU			21
+#define CLK_GPU			22
+#define CLK_EMMC		23
+#define CLK_EMMC_X		24
+#define CLK_AUDIO		25
+#define CLK_HDMI		26
+#define CLK_PMUA_ACLK		27
+#define CLK_PCIE0_MASTER	28
+#define CLK_PCIE0_SLAVE		29
+#define CLK_PCIE0_DBI		30
+#define CLK_PCIE1_MASTER	31
+#define CLK_PCIE1_SLAVE		32
+#define CLK_PCIE1_DBI		33
+#define CLK_PCIE2_MASTER	34
+#define CLK_PCIE2_SLAVE		35
+#define CLK_PCIE2_DBI		36
+#define CLK_EMAC0_BUS		37
+#define CLK_EMAC0_PTP		38
+#define CLK_EMAC1_BUS		39
+#define CLK_EMAC1_PTP		40
+#define CLK_JPG			41
+#define CLK_CCIC2PHY		42
+#define CLK_CCIC3PHY		43
+#define CLK_CSI			44
+#define CLK_CAMM0		45
+#define CLK_CAMM1		46
+#define CLK_CAMM2		47
+#define CLK_ISP_CPP		48
+#define CLK_ISP_BUS		49
+#define CLK_ISP			50
+#define CLK_DPU_MCLK		51
+#define CLK_DPU_ESC		52
+#define CLK_DPU_BIT		53
+#define CLK_DPU_PXCLK		54
+#define CLK_DPU_HCLK		55
+#define CLK_DPU_SPI		56
+#define CLK_DPU_SPI_HBUS	57
+#define CLK_DPU_SPIBUS		58
+#define CLK_DPU_SPI_ACLK	59
+#define CLK_V2D			60
+#define CLK_EMMC_BUS		61
+
+#endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */
--=20
2.49.0
From nobody Tue May 13 04:18:04 2025
Received: from bayard.4d2.org (bayard.4d2.org [155.254.16.17])
	(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 548BF20FA81;
	Tue,  1 Apr 2025 17:24:59 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=155.254.16.17
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743528301; cv=none;
 b=BcaN5wJVKPNxwbLmL6EITdOjd/ujq1F+xoq9T887Zz25m64fBObp5tjjMxjr3VlpkrHxm10s/lGWnv/MU6eTYtxdzMM7MGyUNESBW4DK6NO+AWJHwVQZU4ewGKgsxJuia0z2uuZpMAlMxGwR5IVgmyj8y9SuojGrOZ3RPpIdubY=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743528301; c=relaxed/simple;
	bh=8c6COWP7Dw3rM2JKdudVcfXRIkxcSQg0Ocq+QX4CSfI=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=msEZkzr1RKmFOEGlK60ahO5dWeR16BLi8pxTjl8bSM4Jo59T7y6xuBOO0VfchUbtp4JxGhuc6mEGDwriyd36WjzoyKTs18H9ff6zTnUydkNlfR/w6VYx2GKupxVT9257IjI+z4o2b+B5DFvDsIe8G09ed0Fx/mrDsyiSuc8Hd7w=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org;
 spf=pass smtp.mailfrom=4d2.org;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=YVFozjKd;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=cmCWb2Wv; arc=none smtp.client-ip=155.254.16.17
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="YVFozjKd";
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="cmCWb2Wv"
Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1])
	by bayard.4d2.org (Postfix) with ESMTP id C6559EC59FF;
	Tue, 01 Apr 2025 10:24:58 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528298; bh=8c6COWP7Dw3rM2JKdudVcfXRIkxcSQg0Ocq+QX4CSfI=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=YVFozjKdg42UYsIrQHKCPVuKKIB2zd65HgOw6rd4c4+Zb55bwwpfRG2MZTTYuixvL
	 DRMcoVMRZWpsbbGlNgc+4LRD1z4QbLrAd6ZxojMC89Lscgyoi3bmEiqSJtKpGeDK/u
	 +v0pNxBmoCLqFoE5xAUEfEX7XXolqNz19yk5kVKcV8WbJtwnv4PWBn3FN/uEnMaMdP
	 bRFa2sfQ/P8gErovyf2qvYrZyuAJKc2xG3f5sOgpW/OOZ5JmRFFJSIFKdbw/qFewxE
	 Jzhu/Z7PyhPEaof6hdFZ9YNYlWLGliVVAZgk1R+fwg/pkfpxCsQBAFnDVSYeYOdVM6
	 XgyC+HAEeA5kw==
X-Virus-Scanned: amavisd-new at 4d2.org
Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key)
 header.d=4d2.org
Received: from bayard.4d2.org ([127.0.0.1])
 by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id nie_wgcdoo2K; Tue,  1 Apr 2025 10:24:57 -0700 (PDT)
Received: from localhost.localdomain (unknown [183.217.81.55])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange x25519 server-signature ECDSA (prime256v1) server-digest
 SHA256)
	(No client certificate requested)
	(Authenticated sender: heylenay@4d2.org)
	by bayard.4d2.org (Postfix) with ESMTPSA id 60EC6EC59F9;
	Tue, 01 Apr 2025 10:24:52 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528297; bh=8c6COWP7Dw3rM2JKdudVcfXRIkxcSQg0Ocq+QX4CSfI=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=cmCWb2WvS0S0sSOMt0p6Fk0Ek5jNVTrnK4TqJoWo/WpJbwcXYq7/lT8goDlll+cKv
	 vQMYO3ORaxY+M1l1ehdufm9BW5jyg1jeHI9TrvWx9B2a56PZkx0s/ttwwjSoKPvBk3
	 HjMRsqoq2XSY9oCbvBcKZn8iOcr7h6frrsDRr/FxhC/xhVHNGvrvg2wQMPWrtL6kwd
	 K+Q7ZkTHaH0Hb7umMMgWkaubgic53iqX9HowrxrwLtoPeed7FPFfwXbiQ7ILCsZl9N
	 /TbEdXNQkYAUizzha5LM/irUgG02DKYP7GMWX3KYiW/sb+I8Zj32h4tFDactjRyqKS
	 XSbkjbtMjJJjA==
From: Haylen Chu <heylenay@4d2.org>
To: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Haylen Chu <heylenay@outlook.com>,
	Yixun Lan <dlan@gentoo.org>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>
Cc: linux-riscv@lists.infradead.org,
	linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	spacemit@lists.linux.dev,
	Inochi Amaoto <inochiama@outlook.com>,
	Chen Wang <unicornxdotw@foxmail.com>,
	Jisheng Zhang <jszhang@kernel.org>,
	Meng Zhang <zhangmeng.kevin@linux.spacemit.com>,
	Haylen Chu <heylenay@4d2.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Subject: [PATCH v6 2/6] dt-bindings: clock: spacemit: Add spacemit,k1-pll
Date: Tue,  1 Apr 2025 17:24:30 +0000
Message-ID: <20250401172434.6774-3-heylenay@4d2.org>
X-Mailer: git-send-email 2.49.0
In-Reply-To: <20250401172434.6774-1-heylenay@4d2.org>
References: <20250401172434.6774-1-heylenay@4d2.org>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

Add definition for the PLL found on SpacemiT K1 SoC, which takes the
external 24MHz oscillator as input and generates clocks in various
frequencies for the system.

Signed-off-by: Haylen Chu <heylenay@4d2.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Alex Elder <elder@riscstar.com>
---
 .../bindings/clock/spacemit,k1-pll.yaml       | 50 +++++++++++++++++++
 .../dt-bindings/clock/spacemit,k1-syscon.h    | 37 ++++++++++++++
 2 files changed, 87 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/spacemit,k1-pll=
.yaml

diff --git a/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml b=
/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml
new file mode 100644
index 000000000000..06bafd68c00a
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/spacemit,k1-pll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SpacemiT K1 PLL
+
+maintainers:
+  - Haylen Chu <heylenay@4d2.org>
+
+properties:
+  compatible:
+    const: spacemit,k1-pll
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    description: External 24MHz oscillator
+
+  spacemit,mpmu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the "Main PMU (MPMU)" syscon. It is used to check PLL
+      lock status.
+
+  "#clock-cells":
+    const: 1
+    description:
+      See <dt-bindings/clock/spacemit,k1-syscon.h> for valid indices.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - spacemit,mpmu
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@d4090000 {
+        compatible =3D "spacemit,k1-pll";
+        reg =3D <0xd4090000 0x1000>;
+        clocks =3D <&vctcxo_24m>;
+        spacemit,mpmu =3D <&sysctl_mpmu>;
+        #clock-cells =3D <1>;
+    };
diff --git a/include/dt-bindings/clock/spacemit,k1-syscon.h b/include/dt-bi=
ndings/clock/spacemit,k1-syscon.h
index 61c8d7360cf8..efe29c976a01 100644
--- a/include/dt-bindings/clock/spacemit,k1-syscon.h
+++ b/include/dt-bindings/clock/spacemit,k1-syscon.h
@@ -6,6 +6,43 @@
 #ifndef _DT_BINDINGS_SPACEMIT_CCU_H_
 #define _DT_BINDINGS_SPACEMIT_CCU_H_
=20
+/*	APBS (PLL) clocks	*/
+#define CLK_PLL1		0
+#define CLK_PLL2		1
+#define CLK_PLL3		2
+#define CLK_PLL1_D2		3
+#define CLK_PLL1_D3		4
+#define CLK_PLL1_D4		5
+#define CLK_PLL1_D5		6
+#define CLK_PLL1_D6		7
+#define CLK_PLL1_D7		8
+#define CLK_PLL1_D8		9
+#define CLK_PLL1_D11		10
+#define CLK_PLL1_D13		11
+#define CLK_PLL1_D23		12
+#define CLK_PLL1_D64		13
+#define CLK_PLL1_D10_AUD	14
+#define CLK_PLL1_D100_AUD	15
+#define CLK_PLL2_D1		16
+#define CLK_PLL2_D2		17
+#define CLK_PLL2_D3		18
+#define CLK_PLL2_D4		19
+#define CLK_PLL2_D5		20
+#define CLK_PLL2_D6		21
+#define CLK_PLL2_D7		22
+#define CLK_PLL2_D8		23
+#define CLK_PLL3_D1		24
+#define CLK_PLL3_D2		25
+#define CLK_PLL3_D3		26
+#define CLK_PLL3_D4		27
+#define CLK_PLL3_D5		28
+#define CLK_PLL3_D6		29
+#define CLK_PLL3_D7		30
+#define CLK_PLL3_D8		31
+#define CLK_PLL3_80		32
+#define CLK_PLL3_40		33
+#define CLK_PLL3_20		34
+
 /* MPMU clocks */
 #define CLK_PLL1_307P2		0
 #define CLK_PLL1_76P8		1
--=20
2.49.0
From nobody Tue May 13 04:18:04 2025
Received: from bayard.4d2.org (bayard.4d2.org [155.254.16.17])
	(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 0859B20F072;
	Tue,  1 Apr 2025 17:25:05 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=155.254.16.17
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743528309; cv=none;
 b=jr2rcrMfwCdG1zW8Wvvuo4+gnhGoWhHLFEcKfY5EClp9AqFf1NBlWCj7X7PVdn48carUl2a3x63cFArJ+y8B8L0C1TFUTxUAlyEBN9EK7F4gKlqn7JkxfDf1bad0ygvClSxWWUbBJ+4jBw33iv1R6DWrnFiSpGH0zIoEo0GLvr4=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743528309; c=relaxed/simple;
	bh=YFhs0jbutNuNqKP1+9C9GD0iiWq/lDolSRUHv/6Z3p8=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=VplyJej/hRMfUSxD5yBaMHh54suIJGO5qvDzmMpI9nWE9qOn+yx5M4CPhMc37khq5hwTC5KgvUM44aOSZcWCCqYHRPQDfgmNAeFDdhURR+W9mvWuJ4b8dMrFBskwrbLbJCaOCRIgueJek9qft7qrVD443B77jTCoWDRBFGDv32E=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org;
 spf=pass smtp.mailfrom=4d2.org;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=z4Y50oHZ;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=d5DV0b91; arc=none smtp.client-ip=155.254.16.17
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="z4Y50oHZ";
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="d5DV0b91"
Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1])
	by bayard.4d2.org (Postfix) with ESMTP id 57DCBEC59FE;
	Tue, 01 Apr 2025 10:25:05 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528305; bh=YFhs0jbutNuNqKP1+9C9GD0iiWq/lDolSRUHv/6Z3p8=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=z4Y50oHZPsdEUUnxaipyxI5AolIpRtjkNp9eIZuVYrnzvtpEcOSxxuFabqEN0ACkf
	 nswRMClLc1SnRPmk6eqkLW/K2eGTZPjRfVJUjTal6hhSYr0zJRLhx6zbzrfrD/YXEx
	 CXcYYFJM+SQlO8B0D2B0AK+/qILqCaNbxd6HqytzmDdsi3t8b5cxUU7GPxf2XRt0cr
	 9ySh483cZmCCVoIxnF+/+ERkbYyqIxRXHDcV8rj6Nt1DyD15zx58D2UbOqG7wAMQFj
	 K3yTr5/yXsh5xinTJpltSdcPvUQWOzeFNb+fSZUwF53jEVDJ/F696Y3vYoj1XMf+wL
	 s8Mb/aIlQkuTA==
X-Virus-Scanned: amavisd-new at 4d2.org
Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key)
 header.d=4d2.org
Received: from bayard.4d2.org ([127.0.0.1])
 by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id AZ2KlhlnA8pM; Tue,  1 Apr 2025 10:25:02 -0700 (PDT)
Received: from localhost.localdomain (unknown [183.217.81.55])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange x25519 server-signature ECDSA (prime256v1) server-digest
 SHA256)
	(No client certificate requested)
	(Authenticated sender: heylenay@4d2.org)
	by bayard.4d2.org (Postfix) with ESMTPSA id CBB59EC59FC;
	Tue, 01 Apr 2025 10:24:57 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528302; bh=YFhs0jbutNuNqKP1+9C9GD0iiWq/lDolSRUHv/6Z3p8=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=d5DV0b91/ixxmX7XArfA6PmRjJZVH1z6V+PIhNI11rlK9Y9vqvbf/HZP2CNCTI6nt
	 LT0J0IiLkx28HSQU5r9DkPkVdefeb6uzPloZQLc6Mdb8opQfiQnOnPKAluXU2BUxAR
	 qteLMa44pF+i9y8WXsfJQ4AoaN9nemQmJbEtf3c3QvabbmyIKPRdDvS6dKUm/BzCAI
	 Qm8eytrLb6vJCIUKJvxmV1LjjB57s/+JnQN13ZjwiXtgNTOaL/Ko1u5pYIpTruLKUk
	 qqgfRAfeIWk72PBJ90L33/hLSyJpJjdFOh1OrOo6jWWr19NYgZbDPmTalWjesfOZQh
	 mZdMv0bF82W4A==
From: Haylen Chu <heylenay@4d2.org>
To: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Haylen Chu <heylenay@outlook.com>,
	Yixun Lan <dlan@gentoo.org>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>
Cc: linux-riscv@lists.infradead.org,
	linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	spacemit@lists.linux.dev,
	Inochi Amaoto <inochiama@outlook.com>,
	Chen Wang <unicornxdotw@foxmail.com>,
	Jisheng Zhang <jszhang@kernel.org>,
	Meng Zhang <zhangmeng.kevin@linux.spacemit.com>,
	Haylen Chu <heylenay@4d2.org>
Subject: [PATCH v6 3/6] clk: spacemit: Add clock support for SpacemiT K1 SoC
Date: Tue,  1 Apr 2025 17:24:31 +0000
Message-ID: <20250401172434.6774-4-heylenay@4d2.org>
X-Mailer: git-send-email 2.49.0
In-Reply-To: <20250401172434.6774-1-heylenay@4d2.org>
References: <20250401172434.6774-1-heylenay@4d2.org>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

The clock tree of K1 SoC contains three main types of clock hardware
(PLL/DDN/MIX) and has control registers split into several multifunction
devices: APBS (PLLs), MPMU, APBC and APMU.

All register operations are done through regmap to ensure atomiciy
between concurrent operations of clock driver and reset,
power-domain driver that will be introduced in the future.

Signed-off-by: Haylen Chu <heylenay@4d2.org>
---
 drivers/clk/Kconfig               |    1 +
 drivers/clk/Makefile              |    1 +
 drivers/clk/spacemit/Kconfig      |   18 +
 drivers/clk/spacemit/Makefile     |    5 +
 drivers/clk/spacemit/apbc_clks    |  100 +++
 drivers/clk/spacemit/ccu-k1.c     | 1316 +++++++++++++++++++++++++++++
 drivers/clk/spacemit/ccu_common.h |   48 ++
 drivers/clk/spacemit/ccu_ddn.c    |   83 ++
 drivers/clk/spacemit/ccu_ddn.h    |   47 ++
 drivers/clk/spacemit/ccu_mix.c    |  268 ++++++
 drivers/clk/spacemit/ccu_mix.h    |  218 +++++
 drivers/clk/spacemit/ccu_pll.c    |  157 ++++
 drivers/clk/spacemit/ccu_pll.h    |   86 ++
 13 files changed, 2348 insertions(+)
 create mode 100644 drivers/clk/spacemit/Kconfig
 create mode 100644 drivers/clk/spacemit/Makefile
 create mode 100644 drivers/clk/spacemit/apbc_clks
 create mode 100644 drivers/clk/spacemit/ccu-k1.c
 create mode 100644 drivers/clk/spacemit/ccu_common.h
 create mode 100644 drivers/clk/spacemit/ccu_ddn.c
 create mode 100644 drivers/clk/spacemit/ccu_ddn.h
 create mode 100644 drivers/clk/spacemit/ccu_mix.c
 create mode 100644 drivers/clk/spacemit/ccu_mix.h
 create mode 100644 drivers/clk/spacemit/ccu_pll.c
 create mode 100644 drivers/clk/spacemit/ccu_pll.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 713573b6c86c..19c1ed280fd7 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -517,6 +517,7 @@ source "drivers/clk/samsung/Kconfig"
 source "drivers/clk/sifive/Kconfig"
 source "drivers/clk/socfpga/Kconfig"
 source "drivers/clk/sophgo/Kconfig"
+source "drivers/clk/spacemit/Kconfig"
 source "drivers/clk/sprd/Kconfig"
 source "drivers/clk/starfive/Kconfig"
 source "drivers/clk/sunxi/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index bf4bd45adc3a..42867cd37c33 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -145,6 +145,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG)	+=3D samsung/
 obj-$(CONFIG_CLK_SIFIVE)		+=3D sifive/
 obj-y					+=3D socfpga/
 obj-y					+=3D sophgo/
+obj-y					+=3D spacemit/
 obj-$(CONFIG_PLAT_SPEAR)		+=3D spear/
 obj-y					+=3D sprd/
 obj-$(CONFIG_ARCH_STI)			+=3D st/
diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig
new file mode 100644
index 000000000000..4c4df845b3cb
--- /dev/null
+++ b/drivers/clk/spacemit/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SPACEMIT_CCU
+	tristate "Clock support for SpacemiT SoCs"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	select MFD_SYSCON
+	help
+	  Say Y to enable clock controller unit support for SpacemiT SoCs.
+
+if SPACEMIT_CCU
+
+config SPACEMIT_K1_CCU
+	tristate "Support for SpacemiT K1 SoC"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	help
+	  Support for clock controller unit in SpacemiT K1 SoC.
+
+endif
diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile
new file mode 100644
index 000000000000..5ec6da61db98
--- /dev/null
+++ b/drivers/clk/spacemit/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SPACEMIT_K1_CCU)	=3D spacemit-ccu-k1.o
+spacemit-ccu-k1-y		=3D ccu_pll.o ccu_mix.o ccu_ddn.o
+spacemit-ccu-k1-y		+=3D ccu-k1.o
diff --git a/drivers/clk/spacemit/apbc_clks b/drivers/clk/spacemit/apbc_clks
new file mode 100644
index 000000000000..a65128007063
--- /dev/null
+++ b/drivers/clk/spacemit/apbc_clks
@@ -0,0 +1,100 @@
+		[CLK_UART0]		=3D &uart0_clk.common.hw,
+		[CLK_UART2]		=3D &uart2_clk.common.hw,
+		[CLK_UART3]		=3D &uart3_clk.common.hw,
+		[CLK_UART4]		=3D &uart4_clk.common.hw,
+		[CLK_UART5]		=3D &uart5_clk.common.hw,
+		[CLK_UART6]		=3D &uart6_clk.common.hw,
+		[CLK_UART7]		=3D &uart7_clk.common.hw,
+		[CLK_UART8]		=3D &uart8_clk.common.hw,
+		[CLK_UART9]		=3D &uart9_clk.common.hw,
+		[CLK_GPIO]		=3D &gpio_clk.common.hw,
+		[CLK_PWM0]		=3D &pwm0_clk.common.hw,
+		[CLK_PWM1]		=3D &pwm1_clk.common.hw,
+		[CLK_PWM2]		=3D &pwm2_clk.common.hw,
+		[CLK_PWM3]		=3D &pwm3_clk.common.hw,
+		[CLK_PWM4]		=3D &pwm4_clk.common.hw,
+		[CLK_PWM5]		=3D &pwm5_clk.common.hw,
+		[CLK_PWM6]		=3D &pwm6_clk.common.hw,
+		[CLK_PWM7]		=3D &pwm7_clk.common.hw,
+		[CLK_PWM8]		=3D &pwm8_clk.common.hw,
+		[CLK_PWM9]		=3D &pwm9_clk.common.hw,
+		[CLK_PWM10]		=3D &pwm10_clk.common.hw,
+		[CLK_PWM11]		=3D &pwm11_clk.common.hw,
+		[CLK_PWM12]		=3D &pwm12_clk.common.hw,
+		[CLK_PWM13]		=3D &pwm13_clk.common.hw,
+		[CLK_PWM14]		=3D &pwm14_clk.common.hw,
+		[CLK_PWM15]		=3D &pwm15_clk.common.hw,
+		[CLK_PWM16]		=3D &pwm16_clk.common.hw,
+		[CLK_PWM17]		=3D &pwm17_clk.common.hw,
+		[CLK_PWM18]		=3D &pwm18_clk.common.hw,
+		[CLK_PWM19]		=3D &pwm19_clk.common.hw,
+		[CLK_SSP3]		=3D &ssp3_clk.common.hw,
+		[CLK_RTC]		=3D &rtc_clk.common.hw,
+		[CLK_TWSI0]		=3D &twsi0_clk.common.hw,
+		[CLK_TWSI1]		=3D &twsi1_clk.common.hw,
+		[CLK_TWSI2]		=3D &twsi2_clk.common.hw,
+		[CLK_TWSI4]		=3D &twsi4_clk.common.hw,
+		[CLK_TWSI5]		=3D &twsi5_clk.common.hw,
+		[CLK_TWSI6]		=3D &twsi6_clk.common.hw,
+		[CLK_TWSI7]		=3D &twsi7_clk.common.hw,
+		[CLK_TWSI8]		=3D &twsi8_clk.common.hw,
+		[CLK_TIMERS1]		=3D &timers1_clk.common.hw,
+		[CLK_TIMERS2]		=3D &timers2_clk.common.hw,
+		[CLK_AIB]		=3D &aib_clk.common.hw,
+		[CLK_ONEWIRE]		=3D &onewire_clk.common.hw,
+		[CLK_SSPA0]		=3D &sspa0_clk.common.hw,
+		[CLK_SSPA1]		=3D &sspa1_clk.common.hw,
+		[CLK_DRO]		=3D &dro_clk.common.hw,
+		[CLK_IR]		=3D &ir_clk.common.hw,
+		[CLK_TSEN]		=3D &tsen_clk.common.hw,
+		[CLK_IPC_AP2AUD]	=3D &ipc_ap2aud_clk.common.hw,
+		[CLK_CAN0]		=3D &can0_clk.common.hw,
+		[CLK_CAN0_BUS]		=3D &can0_bus_clk.common.hw,
+		[CLK_UART0_BUS]		=3D &uart0_bus_clk.common.hw,
+		[CLK_UART2_BUS]		=3D &uart2_bus_clk.common.hw,
+		[CLK_UART3_BUS]		=3D &uart3_bus_clk.common.hw,
+		[CLK_UART4_BUS]		=3D &uart4_bus_clk.common.hw,
+		[CLK_UART5_BUS]		=3D &uart5_bus_clk.common.hw,
+		[CLK_UART6_BUS]		=3D &uart6_bus_clk.common.hw,
+		[CLK_UART7_BUS]		=3D &uart7_bus_clk.common.hw,
+		[CLK_UART8_BUS]		=3D &uart8_bus_clk.common.hw,
+		[CLK_UART9_BUS]		=3D &uart9_bus_clk.common.hw,
+		[CLK_GPIO_BUS]		=3D &gpio_bus_clk.common.hw,
+		[CLK_PWM0_BUS]		=3D &pwm0_bus_clk.common.hw,
+		[CLK_PWM1_BUS]		=3D &pwm1_bus_clk.common.hw,
+		[CLK_PWM2_BUS]		=3D &pwm2_bus_clk.common.hw,
+		[CLK_PWM3_BUS]		=3D &pwm3_bus_clk.common.hw,
+		[CLK_PWM4_BUS]		=3D &pwm4_bus_clk.common.hw,
+		[CLK_PWM5_BUS]		=3D &pwm5_bus_clk.common.hw,
+		[CLK_PWM6_BUS]		=3D &pwm6_bus_clk.common.hw,
+		[CLK_PWM7_BUS]		=3D &pwm7_bus_clk.common.hw,
+		[CLK_PWM8_BUS]		=3D &pwm8_bus_clk.common.hw,
+		[CLK_PWM9_BUS]		=3D &pwm9_bus_clk.common.hw,
+		[CLK_PWM10_BUS]		=3D &pwm10_bus_clk.common.hw,
+		[CLK_PWM11_BUS]		=3D &pwm11_bus_clk.common.hw,
+		[CLK_PWM12_BUS]		=3D &pwm12_bus_clk.common.hw,
+		[CLK_PWM13_BUS]		=3D &pwm13_bus_clk.common.hw,
+		[CLK_PWM14_BUS]		=3D &pwm14_bus_clk.common.hw,
+		[CLK_PWM15_BUS]		=3D &pwm15_bus_clk.common.hw,
+		[CLK_PWM16_BUS]		=3D &pwm16_bus_clk.common.hw,
+		[CLK_PWM17_BUS]		=3D &pwm17_bus_clk.common.hw,
+		[CLK_PWM18_BUS]		=3D &pwm18_bus_clk.common.hw,
+		[CLK_PWM19_BUS]		=3D &pwm19_bus_clk.common.hw,
+		[CLK_SSP3_BUS]		=3D &ssp3_bus_clk.common.hw,
+		[CLK_RTC_BUS]		=3D &rtc_bus_clk.common.hw,
+		[CLK_TWSI0_BUS]		=3D &twsi0_bus_clk.common.hw,
+		[CLK_TWSI1_BUS]		=3D &twsi1_bus_clk.common.hw,
+		[CLK_TWSI2_BUS]		=3D &twsi2_bus_clk.common.hw,
+		[CLK_TWSI4_BUS]		=3D &twsi4_bus_clk.common.hw,
+		[CLK_TWSI5_BUS]		=3D &twsi5_bus_clk.common.hw,
+		[CLK_TWSI6_BUS]		=3D &twsi6_bus_clk.common.hw,
+		[CLK_TWSI7_BUS]		=3D &twsi7_bus_clk.common.hw,
+		[CLK_TWSI8_BUS]		=3D &twsi8_bus_clk.common.hw,
+		[CLK_TIMERS1_BUS]	=3D &timers1_bus_clk.common.hw,
+		[CLK_TIMERS2_BUS]	=3D &timers2_bus_clk.common.hw,
+		[CLK_AIB_BUS]		=3D &aib_bus_clk.common.hw,
+		[CLK_ONEWIRE_BUS]	=3D &onewire_bus_clk.common.hw,
+		[CLK_SSPA0_BUS]		=3D &sspa0_bus_clk.common.hw,
+		[CLK_SSPA1_BUS]		=3D &sspa1_bus_clk.common.hw,
+		[CLK_TSEN_BUS]		=3D &tsen_bus_clk.common.hw,
+		[CLK_IPC_AP2AUD_BUS]	=3D &ipc_ap2aud_bus_clk.common.hw,
diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
new file mode 100644
index 000000000000..cd95c4f9c127
--- /dev/null
+++ b/drivers/clk/spacemit/ccu-k1.c
@@ -0,0 +1,1316 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org>
+ */
+
+#include <linux/array_size.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/minmax.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_pll.h"
+#include "ccu_mix.h"
+#include "ccu_ddn.h"
+
+#include <dt-bindings/clock/spacemit,k1-syscon.h>
+
+/* APBS register offset */
+#define APBS_PLL1_SWCR1			0x100
+#define APBS_PLL1_SWCR2			0x104
+#define APBS_PLL1_SWCR3			0x108
+#define APBS_PLL2_SWCR1			0x118
+#define APBS_PLL2_SWCR2			0x11c
+#define APBS_PLL2_SWCR3			0x120
+#define APBS_PLL3_SWCR1			0x124
+#define APBS_PLL3_SWCR2			0x128
+#define APBS_PLL3_SWCR3			0x12c
+
+/* MPMU register offset */
+#define MPMU_POSR			0x0010
+#define  POSR_PLL1_LOCK			BIT(27)
+#define  POSR_PLL2_LOCK			BIT(28)
+#define  POSR_PLL3_LOCK			BIT(29)
+#define MPMU_SUCCR			0x0014
+#define MPMU_ISCCR			0x0044
+#define MPMU_WDTPCR			0x0200
+#define MPMU_RIPCCR			0x0210
+#define MPMU_ACGR			0x1024
+#define MPMU_APBCSCR			0x1050
+#define MPMU_SUCCR_1			0x10b0
+
+/* APBC register offset */
+#define APBC_UART1_CLK_RST		0x00
+#define APBC_UART2_CLK_RST		0x04
+#define APBC_GPIO_CLK_RST		0x08
+#define APBC_PWM0_CLK_RST		0x0c
+#define APBC_PWM1_CLK_RST		0x10
+#define APBC_PWM2_CLK_RST		0x14
+#define APBC_PWM3_CLK_RST		0x18
+#define APBC_TWSI8_CLK_RST		0x20
+#define APBC_UART3_CLK_RST		0x24
+#define APBC_RTC_CLK_RST		0x28
+#define APBC_TWSI0_CLK_RST		0x2c
+#define APBC_TWSI1_CLK_RST		0x30
+#define APBC_TIMERS1_CLK_RST		0x34
+#define APBC_TWSI2_CLK_RST		0x38
+#define APBC_AIB_CLK_RST		0x3c
+#define APBC_TWSI4_CLK_RST		0x40
+#define APBC_TIMERS2_CLK_RST		0x44
+#define APBC_ONEWIRE_CLK_RST		0x48
+#define APBC_TWSI5_CLK_RST		0x4c
+#define APBC_DRO_CLK_RST		0x58
+#define APBC_IR_CLK_RST			0x5c
+#define APBC_TWSI6_CLK_RST		0x60
+#define APBC_COUNTER_CLK_SEL		0x64
+#define APBC_TWSI7_CLK_RST		0x68
+#define APBC_TSEN_CLK_RST		0x6c
+#define APBC_UART4_CLK_RST		0x70
+#define APBC_UART5_CLK_RST		0x74
+#define APBC_UART6_CLK_RST		0x78
+#define APBC_SSP3_CLK_RST		0x7c
+#define APBC_SSPA0_CLK_RST		0x80
+#define APBC_SSPA1_CLK_RST		0x84
+#define APBC_IPC_AP2AUD_CLK_RST		0x90
+#define APBC_UART7_CLK_RST		0x94
+#define APBC_UART8_CLK_RST		0x98
+#define APBC_UART9_CLK_RST		0x9c
+#define APBC_CAN0_CLK_RST		0xa0
+#define APBC_PWM4_CLK_RST		0xa8
+#define APBC_PWM5_CLK_RST		0xac
+#define APBC_PWM6_CLK_RST		0xb0
+#define APBC_PWM7_CLK_RST		0xb4
+#define APBC_PWM8_CLK_RST		0xb8
+#define APBC_PWM9_CLK_RST		0xbc
+#define APBC_PWM10_CLK_RST		0xc0
+#define APBC_PWM11_CLK_RST		0xc4
+#define APBC_PWM12_CLK_RST		0xc8
+#define APBC_PWM13_CLK_RST		0xcc
+#define APBC_PWM14_CLK_RST		0xd0
+#define APBC_PWM15_CLK_RST		0xd4
+#define APBC_PWM16_CLK_RST		0xd8
+#define APBC_PWM17_CLK_RST		0xdc
+#define APBC_PWM18_CLK_RST		0xe0
+#define APBC_PWM19_CLK_RST		0xe4
+
+/* APMU register offset */
+#define APMU_JPG_CLK_RES_CTRL		0x020
+#define APMU_CSI_CCIC2_CLK_RES_CTRL	0x024
+#define APMU_ISP_CLK_RES_CTRL		0x038
+#define APMU_LCD_CLK_RES_CTRL1		0x044
+#define APMU_LCD_SPI_CLK_RES_CTRL	0x048
+#define APMU_LCD_CLK_RES_CTRL2		0x04c
+#define APMU_CCIC_CLK_RES_CTRL		0x050
+#define APMU_SDH0_CLK_RES_CTRL		0x054
+#define APMU_SDH1_CLK_RES_CTRL		0x058
+#define APMU_USB_CLK_RES_CTRL		0x05c
+#define APMU_QSPI_CLK_RES_CTRL		0x060
+#define APMU_DMA_CLK_RES_CTRL		0x064
+#define APMU_AES_CLK_RES_CTRL		0x068
+#define APMU_VPU_CLK_RES_CTRL		0x0a4
+#define APMU_GPU_CLK_RES_CTRL		0x0cc
+#define APMU_SDH2_CLK_RES_CTRL		0x0e0
+#define APMU_PMUA_MC_CTRL		0x0e8
+#define APMU_PMU_CC2_AP			0x100
+#define APMU_PMUA_EM_CLK_RES_CTRL	0x104
+#define APMU_AUDIO_CLK_RES_CTRL		0x14c
+#define APMU_HDMI_CLK_RES_CTRL		0x1b8
+#define APMU_CCI550_CLK_CTRL		0x300
+#define APMU_ACLK_CLK_CTRL		0x388
+#define APMU_CPU_C0_CLK_CTRL		0x38C
+#define APMU_CPU_C1_CLK_CTRL		0x390
+#define APMU_PCIE_CLK_RES_CTRL_0	0x3cc
+#define APMU_PCIE_CLK_RES_CTRL_1	0x3d4
+#define APMU_PCIE_CLK_RES_CTRL_2	0x3dc
+#define APMU_EMAC0_CLK_RES_CTRL		0x3e4
+#define APMU_EMAC1_CLK_RES_CTRL		0x3ec
+
+/* APBS clocks start, APBS region contains and only contains all PLL clock=
s */
+
+/* Frequency of pll{1,2} must not be updated at runtime */
+static const struct ccu_pll_rate_tbl pll1_rate_tbl[] =3D {
+	CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),
+};
+
+static const struct ccu_pll_rate_tbl pll2_rate_tbl[] =3D {
+	CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),
+	CCU_PLL_RATE(2800000000UL, 0x0050dd66, 0x3a155555),
+	CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000),
+	CCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab),
+};
+
+static const struct ccu_pll_rate_tbl pll3_rate_tbl[] =3D {
+	CCU_PLL_RATE(1600000000UL, 0x0050cd61, 0x43eaaaab),
+	CCU_PLL_RATE(1800000000UL, 0x0050cd61, 0x4b000000),
+	CCU_PLL_RATE(2000000000UL, 0x0050dd62, 0x2aeaaaab),
+	CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd),
+	CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000),
+	CCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab),
+};
+
+CCU_PLL_DEFINE(pll1, pll1_rate_tbl, APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, MPMU=
_POSR,
+	       POSR_PLL1_LOCK, CLK_SET_RATE_GATE);
+CCU_PLL_DEFINE(pll2, pll2_rate_tbl, APBS_PLL2_SWCR1, APBS_PLL2_SWCR3, MPMU=
_POSR,
+	       POSR_PLL2_LOCK, CLK_SET_RATE_GATE);
+CCU_PLL_DEFINE(pll3, pll3_rate_tbl, APBS_PLL3_SWCR1, APBS_PLL3_SWCR3, MPMU=
_POSR,
+	       POSR_PLL3_LOCK, CLK_SET_RATE_GATE);
+
+CCU_FACTOR_GATE_DEFINE(pll1_d2, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(=
1), 2,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll1_d3, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(=
2), 3,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll1_d4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(=
3), 4,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll1_d5, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(=
4), 5,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll1_d6, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(=
5), 6,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll1_d7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(=
6), 7,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll1_d8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(=
7), 8,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll1_d11_223p4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR=
2,
+		       BIT(15), 11, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d13_189, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2,
+		       BIT(16), 13, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d23_106p8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR=
2,
+		       BIT(20), 23, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d64_38p4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2,
+		       BIT(0), 64, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_aud_245p7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR=
2,
+		       BIT(10), 10, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_aud_24p5, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2,
+		       BIT(11), 100, 1);
+
+CCU_FACTOR_GATE_DEFINE(pll2_d1, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(=
0), 1,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll2_d2, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(=
1), 2,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll2_d3, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(=
2), 3,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll2_d4, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(=
3), 4,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll2_d5, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(=
4), 5,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll2_d6, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(=
5), 6,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll2_d7, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(=
6), 7,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll2_d8, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(=
7), 8,
+		       1);
+
+CCU_FACTOR_GATE_DEFINE(pll3_d1, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(=
0), 1,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll3_d2, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(=
1), 2,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll3_d3, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(=
2), 3,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll3_d4, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(=
3), 4,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll3_d5, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(=
4), 5,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll3_d6, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(=
5), 6,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll3_d7, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(=
6), 7,
+		       1);
+CCU_FACTOR_GATE_DEFINE(pll3_d8, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(=
7), 8,
+		       1);
+
+CCU_FACTOR_DEFINE(pll3_20, CCU_PARENT_HW(pll3_d8), 20, 1);
+CCU_FACTOR_DEFINE(pll3_40, CCU_PARENT_HW(pll3_d8), 10, 1);
+CCU_FACTOR_DEFINE(pll3_80, CCU_PARENT_HW(pll3_d8), 5, 1);
+
+/* APBS clocks end */
+
+/* MPMU clocks start */
+CCU_GATE_DEFINE(pll1_d8_307p2, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(13),=
 0);
+
+CCU_FACTOR_DEFINE(pll1_d32_76p8, CCU_PARENT_HW(pll1_d8_307p2), 4, 1);
+
+CCU_FACTOR_DEFINE(pll1_d40_61p44, CCU_PARENT_HW(pll1_d8_307p2), 5, 1);
+
+CCU_FACTOR_DEFINE(pll1_d16_153p6, CCU_PARENT_HW(pll1_d8), 2, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d24_102p4, CCU_PARENT_HW(pll1_d8), MPMU_ACGR,
+		       BIT(12), 3, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d48_51p2, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, B=
IT(7),
+		       6, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d48_51p2_ap, CCU_PARENT_HW(pll1_d8), MPMU_ACGR,
+		       BIT(11), 6, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_m3d128_57p6, CCU_PARENT_HW(pll1_d8), MPMU_ACGR,
+		       BIT(8), 16, 3);
+CCU_FACTOR_GATE_DEFINE(pll1_d96_25p6, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, B=
IT(4),
+		       12, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d192_12p8, CCU_PARENT_HW(pll1_d8), MPMU_ACGR,
+		       BIT(3), 24, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d192_12p8_wdt, CCU_PARENT_HW(pll1_d8), MPMU_AC=
GR,
+		       BIT(19), 24, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d384_6p4, CCU_PARENT_HW(pll1_d8), MPMU_ACGR,
+		       BIT(2), 48, 1);
+
+CCU_FACTOR_DEFINE(pll1_d768_3p2, CCU_PARENT_HW(pll1_d384_6p4), 2, 1);
+CCU_FACTOR_DEFINE(pll1_d1536_1p6, CCU_PARENT_HW(pll1_d384_6p4), 4, 1);
+CCU_FACTOR_DEFINE(pll1_d3072_0p8, CCU_PARENT_HW(pll1_d384_6p4), 8, 1);
+
+CCU_GATE_DEFINE(pll1_d6_409p6, CCU_PARENT_HW(pll1_d6), MPMU_ACGR, BIT(0), =
0);
+CCU_FACTOR_GATE_DEFINE(pll1_d12_204p8, CCU_PARENT_HW(pll1_d6), MPMU_ACGR,
+		       BIT(5), 2, 1);
+
+CCU_GATE_DEFINE(pll1_d5_491p52, CCU_PARENT_HW(pll1_d5), MPMU_ACGR, BIT(21)=
, 0);
+CCU_FACTOR_GATE_DEFINE(pll1_d10_245p76, CCU_PARENT_HW(pll1_d5), MPMU_ACGR,
+		       BIT(18), 2, 1);
+
+CCU_GATE_DEFINE(pll1_d4_614p4, CCU_PARENT_HW(pll1_d4), MPMU_ACGR,
+		BIT(15), 0);
+CCU_FACTOR_GATE_DEFINE(pll1_d52_47p26, CCU_PARENT_HW(pll1_d4), MPMU_ACGR,
+		       BIT(10), 13, 1);
+CCU_FACTOR_GATE_DEFINE(pll1_d78_31p5, CCU_PARENT_HW(pll1_d4), MPMU_ACGR,
+		       BIT(6), 39, 2);
+
+CCU_GATE_DEFINE(pll1_d3_819p2, CCU_PARENT_HW(pll1_d3), MPMU_ACGR, BIT(14),=
 0);
+
+CCU_GATE_DEFINE(pll1_d2_1228p8, CCU_PARENT_HW(pll1_d2), MPMU_ACGR, BIT(16)=
, 0);
+
+CCU_GATE_DEFINE(slow_uart, CCU_PARENT_NAME(osc), MPMU_ACGR, BIT(1),
+		CLK_IGNORE_UNUSED);
+CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, MPMU_SUCCR, GENMASK(28, 1=
6),
+	       GENMASK(12, 0), 0);
+CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, MPMU_SUCCR_1, GENMASK(28, 16),
+	       GENMASK(12, 0), 0);
+
+CCU_GATE_DEFINE(wdt_clk, CCU_PARENT_HW(pll1_d96_25p6), MPMU_WDTPCR, BIT(1)=
, 0);
+
+CCU_FACTOR_GATE_DEFINE(i2s_sysclk, CCU_PARENT_HW(pll1_d16_153p6), MPMU_ISC=
CR,
+		       BIT(31), 50, 1);
+CCU_FACTOR_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s_sysclk), MPMU_ISCCR, BI=
T(29),
+		       1, 1);
+
+static const struct clk_parent_data apb_parents[] =3D {
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d48_51p2),
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d24_102p4),
+};
+CCU_MUX_DEFINE(apb_clk, apb_parents, MPMU_APBCSCR, 0, 2, 0);
+
+CCU_GATE_DEFINE(wdt_bus_clk, CCU_PARENT_HW(apb_clk), MPMU_WDTPCR, BIT(0), =
0);
+
+CCU_GATE_DEFINE(ripc_clk, CCU_PARENT_HW(apb_clk), MPMU_RIPCCR, 0x1, 0);
+/* MPMU clocks end */
+
+/* APBC clocks start */
+static const struct clk_parent_data uart_clk_parents[] =3D {
+	CCU_PARENT_HW(pll1_m3d128_57p6),
+	CCU_PARENT_HW(slow_uart1_14p74),
+	CCU_PARENT_HW(slow_uart2_48),
+};
+CCU_MUX_GATE_DEFINE(uart0_clk, uart_clk_parents, APBC_UART1_CLK_RST, 4, 3,
+		    BIT(1), CLK_IS_CRITICAL);
+CCU_MUX_GATE_DEFINE(uart2_clk, uart_clk_parents, APBC_UART2_CLK_RST, 4, 3,
+		    BIT(1), 0);
+CCU_MUX_GATE_DEFINE(uart3_clk, uart_clk_parents, APBC_UART3_CLK_RST, 4, 3,
+		    BIT(1), 0);
+CCU_MUX_GATE_DEFINE(uart4_clk, uart_clk_parents, APBC_UART4_CLK_RST, 4, 3,
+		    BIT(1), 0);
+CCU_MUX_GATE_DEFINE(uart5_clk, uart_clk_parents, APBC_UART5_CLK_RST, 4, 3,
+		    BIT(1), 0);
+CCU_MUX_GATE_DEFINE(uart6_clk, uart_clk_parents, APBC_UART6_CLK_RST, 4, 3,
+		    BIT(1), 0);
+CCU_MUX_GATE_DEFINE(uart7_clk, uart_clk_parents, APBC_UART7_CLK_RST, 4, 3,
+		    BIT(1), 0);
+CCU_MUX_GATE_DEFINE(uart8_clk, uart_clk_parents, APBC_UART8_CLK_RST, 4, 3,
+		    BIT(1), 0);
+CCU_MUX_GATE_DEFINE(uart9_clk, uart_clk_parents, APBC_UART9_CLK_RST, 4, 3,
+		    BIT(1), 0);
+
+CCU_GATE_DEFINE(gpio_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_GPIO_CLK_RST,
+		BIT(1), 0);
+
+static const struct clk_parent_data pwm_parents[] =3D {
+	CCU_PARENT_HW(pll1_d192_12p8),
+	CCU_PARENT_NAME(osc),
+};
+CCU_MUX_GATE_DEFINE(pwm0_clk, pwm_parents, APBC_PWM0_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm1_clk, pwm_parents, APBC_PWM1_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm2_clk, pwm_parents, APBC_PWM2_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm3_clk, pwm_parents, APBC_PWM3_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm4_clk, pwm_parents, APBC_PWM4_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm5_clk, pwm_parents, APBC_PWM5_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm6_clk, pwm_parents, APBC_PWM6_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm7_clk, pwm_parents, APBC_PWM7_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm8_clk, pwm_parents, APBC_PWM8_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm9_clk, pwm_parents, APBC_PWM9_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_MUX_GATE_DEFINE(pwm10_clk, pwm_parents, APBC_PWM10_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm11_clk, pwm_parents, APBC_PWM11_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm12_clk, pwm_parents, APBC_PWM12_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm13_clk, pwm_parents, APBC_PWM13_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm14_clk, pwm_parents, APBC_PWM14_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm15_clk, pwm_parents, APBC_PWM15_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm16_clk, pwm_parents, APBC_PWM16_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm17_clk, pwm_parents, APBC_PWM17_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm18_clk, pwm_parents, APBC_PWM18_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+CCU_MUX_GATE_DEFINE(pwm19_clk, pwm_parents, APBC_PWM19_CLK_RST, 4, 3, BIT(=
1),
+		    0);
+
+static const struct clk_parent_data ssp_parents[] =3D {
+	CCU_PARENT_HW(pll1_d384_6p4),
+	CCU_PARENT_HW(pll1_d192_12p8),
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d48_51p2),
+	CCU_PARENT_HW(pll1_d768_3p2),
+	CCU_PARENT_HW(pll1_d1536_1p6),
+	CCU_PARENT_HW(pll1_d3072_0p8),
+};
+CCU_MUX_GATE_DEFINE(ssp3_clk, ssp_parents, APBC_SSP3_CLK_RST, 4, 3, BIT(1)=
, 0);
+
+CCU_GATE_DEFINE(rtc_clk, CCU_PARENT_NAME(osc), APBC_RTC_CLK_RST,
+		BIT(7) | BIT(1), 0);
+
+static const struct clk_parent_data twsi_parents[] =3D {
+	CCU_PARENT_HW(pll1_d78_31p5),
+	CCU_PARENT_HW(pll1_d48_51p2),
+	CCU_PARENT_HW(pll1_d40_61p44),
+};
+CCU_MUX_GATE_DEFINE(twsi0_clk, twsi_parents, APBC_TWSI0_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+CCU_MUX_GATE_DEFINE(twsi1_clk, twsi_parents, APBC_TWSI1_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+CCU_MUX_GATE_DEFINE(twsi2_clk, twsi_parents, APBC_TWSI2_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+CCU_MUX_GATE_DEFINE(twsi4_clk, twsi_parents, APBC_TWSI4_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+CCU_MUX_GATE_DEFINE(twsi5_clk, twsi_parents, APBC_TWSI5_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+CCU_MUX_GATE_DEFINE(twsi6_clk, twsi_parents, APBC_TWSI6_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+CCU_MUX_GATE_DEFINE(twsi7_clk, twsi_parents, APBC_TWSI7_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+
+static const struct clk_parent_data timer_parents[] =3D {
+	CCU_PARENT_HW(pll1_d192_12p8),
+	CCU_PARENT_NAME(osc),
+	CCU_PARENT_HW(pll1_d384_6p4),
+	CCU_PARENT_NAME(vctcxo_3m),
+	CCU_PARENT_NAME(vctcxo_1m),
+};
+CCU_MUX_GATE_DEFINE(timers1_clk, timer_parents, APBC_TIMERS1_CLK_RST, 4, 3,
+		    BIT(1), 0);
+CCU_MUX_GATE_DEFINE(timers2_clk, timer_parents, APBC_TIMERS2_CLK_RST, 4, 3,
+		    BIT(1), 0);
+
+CCU_GATE_DEFINE(aib_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_AIB_CLK_RST, BI=
T(1),
+		0);
+
+CCU_GATE_DEFINE(onewire_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_ONEWIRE_CLK=
_RST,
+		BIT(1), 0);
+
+static const struct clk_parent_data sspa_parents[] =3D {
+	CCU_PARENT_HW(pll1_d384_6p4),
+	CCU_PARENT_HW(pll1_d192_12p8),
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d48_51p2),
+	CCU_PARENT_HW(pll1_d768_3p2),
+	CCU_PARENT_HW(pll1_d1536_1p6),
+	CCU_PARENT_HW(pll1_d3072_0p8),
+	CCU_PARENT_HW(i2s_bclk),
+};
+CCU_MUX_GATE_DEFINE(sspa0_clk, sspa_parents, APBC_SSPA0_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+CCU_MUX_GATE_DEFINE(sspa1_clk, sspa_parents, APBC_SSPA1_CLK_RST, 4, 3, BIT=
(1),
+		    0);
+CCU_GATE_DEFINE(dro_clk, CCU_PARENT_HW(apb_clk), APBC_DRO_CLK_RST, BIT(1),=
 0);
+CCU_GATE_DEFINE(ir_clk, CCU_PARENT_HW(apb_clk), APBC_IR_CLK_RST, BIT(1), 0=
);
+CCU_GATE_DEFINE(tsen_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, BIT(1=
), 0);
+CCU_GATE_DEFINE(ipc_ap2aud_clk, CCU_PARENT_HW(apb_clk), APBC_IPC_AP2AUD_CL=
K_RST,
+		BIT(1), 0);
+
+static const struct clk_parent_data can_parents[] =3D {
+	CCU_PARENT_HW(pll3_20),
+	CCU_PARENT_HW(pll3_40),
+	CCU_PARENT_HW(pll3_80),
+};
+CCU_MUX_GATE_DEFINE(can0_clk, can_parents, APBC_CAN0_CLK_RST, 4, 3, BIT(1)=
, 0);
+CCU_GATE_DEFINE(can0_bus_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_CAN0_CLK_R=
ST,
+		BIT(0), 0);
+
+CCU_GATE_DEFINE(uart0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART1_CLK_RST,
+		BIT(0), CLK_IS_CRITICAL);
+CCU_GATE_DEFINE(uart2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART2_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(uart3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART3_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(uart4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART4_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(uart5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART5_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(uart6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART6_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(uart7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART7_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(uart8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART8_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(uart9_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART9_CLK_RST,
+		BIT(0), 0);
+
+CCU_GATE_DEFINE(gpio_bus_clk, CCU_PARENT_HW(apb_clk), APBC_GPIO_CLK_RST, B=
IT(0),
+		0);
+
+CCU_GATE_DEFINE(pwm0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM0_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM1_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM2_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM3_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM4_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM5_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM6_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM7_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM8_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm9_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM9_CLK_RST, B=
IT(0),
+		0);
+CCU_GATE_DEFINE(pwm10_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM10_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm11_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM11_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm12_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM12_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm13_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM13_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm14_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM14_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm15_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM15_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm16_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM16_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm17_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM17_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm18_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM18_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(pwm19_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM19_CLK_RST,
+		BIT(0), 0);
+
+CCU_GATE_DEFINE(ssp3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSP3_CLK_RST, B=
IT(0),
+		0);
+
+CCU_GATE_DEFINE(rtc_bus_clk, CCU_PARENT_HW(apb_clk), APBC_RTC_CLK_RST, BIT=
(0),
+		0);
+
+CCU_GATE_DEFINE(twsi0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI0_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(twsi1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI1_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(twsi2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI2_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(twsi4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI4_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(twsi5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI5_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(twsi6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI6_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(twsi7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI7_CLK_RST,
+		BIT(0), 0);
+
+CCU_GATE_DEFINE(timers1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS1_CLK_=
RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(timers2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS2_CLK_=
RST,
+		BIT(0), 0);
+
+CCU_GATE_DEFINE(aib_bus_clk, CCU_PARENT_HW(apb_clk), APBC_AIB_CLK_RST, BIT=
(0),
+		0);
+
+CCU_GATE_DEFINE(onewire_bus_clk, CCU_PARENT_HW(apb_clk), APBC_ONEWIRE_CLK_=
RST,
+		BIT(0), 0);
+
+CCU_GATE_DEFINE(sspa0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA0_CLK_RST,
+		BIT(0), 0);
+CCU_GATE_DEFINE(sspa1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA1_CLK_RST,
+		BIT(0), 0);
+
+CCU_GATE_DEFINE(tsen_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, B=
IT(0),
+		0);
+
+CCU_GATE_DEFINE(ipc_ap2aud_bus_clk, CCU_PARENT_HW(apb_clk),
+		APBC_IPC_AP2AUD_CLK_RST, BIT(0), 0);
+/* APBC clocks end */
+
+/* APMU clocks start */
+static const struct clk_parent_data pmua_aclk_parents[] =3D {
+	CCU_PARENT_HW(pll1_d10_245p76),
+	CCU_PARENT_HW(pll1_d8_307p2),
+};
+CCU_MUX_DIV_FC_DEFINE(pmua_aclk, pmua_aclk_parents, APMU_ACLK_CLK_CTRL, 1,=
 2,
+		      BIT(4), 0, 1, 0);
+
+static const struct clk_parent_data cci550_clk_parents[] =3D {
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll2_d3),
+};
+CCU_MUX_DIV_FC_DEFINE(cci550_clk, cci550_clk_parents, APMU_CCI550_CLK_CTRL=
, 8,
+		      3, BIT(12), 0, 2, CLK_IS_CRITICAL);
+
+static const struct clk_parent_data cpu_c0_hi_clk_parents[] =3D {
+	CCU_PARENT_HW(pll3_d2),
+	CCU_PARENT_HW(pll3_d1),
+};
+CCU_MUX_DEFINE(cpu_c0_hi_clk, cpu_c0_hi_clk_parents, APMU_CPU_C0_CLK_CTRL,=
 13,
+	       1, 0);
+static const struct clk_parent_data cpu_c0_clk_parents[] =3D {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+	CCU_PARENT_HW(pll3_d3),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(cpu_c0_hi_clk),
+};
+CCU_MUX_FC_DEFINE(cpu_c0_core_clk, cpu_c0_clk_parents, APMU_CPU_C0_CLK_CTR=
L,
+		  BIT(12), 0, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(cpu_c0_ace_clk, CCU_PARENT_HW(cpu_c0_core_clk),
+	       APMU_CPU_C0_CLK_CTRL, 6, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(cpu_c0_tcm_clk, CCU_PARENT_HW(cpu_c0_core_clk),
+	       APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL);
+
+static const struct clk_parent_data cpu_c1_hi_clk_parents[] =3D {
+	CCU_PARENT_HW(pll3_d2),
+	CCU_PARENT_HW(pll3_d1),
+};
+CCU_MUX_DEFINE(cpu_c1_hi_clk, cpu_c1_hi_clk_parents, APMU_CPU_C1_CLK_CTRL,=
 13,
+	       1, CLK_IS_CRITICAL);
+static const struct clk_parent_data cpu_c1_clk_parents[] =3D {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+	CCU_PARENT_HW(pll3_d3),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(cpu_c1_hi_clk),
+};
+CCU_MUX_FC_DEFINE(cpu_c1_core_clk, cpu_c1_clk_parents, APMU_CPU_C1_CLK_CTR=
L,
+		  BIT(12), 0, 3, CLK_IS_CRITICAL);
+CCU_DIV_DEFINE(cpu_c1_ace_clk, CCU_PARENT_HW(cpu_c1_core_clk),
+	       APMU_CPU_C1_CLK_CTRL, 6, 3, CLK_IS_CRITICAL);
+
+static const struct clk_parent_data jpg_parents[] =3D {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll2_d3),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(jpg_clk, jpg_parents, APMU_JPG_CLK_RES_CTRL, 5,=
 3,
+			   BIT(15), 2, 3, BIT(1), 0);
+
+static const struct clk_parent_data ccic2phy_parents[] =3D {
+	CCU_PARENT_HW(pll1_d24_102p4),
+	CCU_PARENT_HW(pll1_d48_51p2_ap),
+};
+CCU_MUX_GATE_DEFINE(ccic2phy_clk, ccic2phy_parents, APMU_CSI_CCIC2_CLK_RES=
_CTRL,
+		    7, 1, BIT(5), 0);
+
+static const struct clk_parent_data ccic3phy_parents[] =3D {
+	CCU_PARENT_HW(pll1_d24_102p4),
+	CCU_PARENT_HW(pll1_d48_51p2_ap),
+};
+CCU_MUX_GATE_DEFINE(ccic3phy_clk, ccic3phy_parents, APMU_CSI_CCIC2_CLK_RES=
_CTRL,
+		    31, 1, BIT(30), 0);
+
+static const struct clk_parent_data csi_parents[] =3D {
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll2_d2),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(csi_clk, csi_parents, APMU_CSI_CCIC2_CLK_RES_CT=
RL,
+			   20, 3, BIT(15), 16, 3, BIT(4), 0);
+
+static const struct clk_parent_data camm_parents[] =3D {
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll2_d5),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_NAME(vctcxo_24m),
+};
+CCU_MUX_DIV_GATE_DEFINE(camm0_clk, camm_parents, APMU_CSI_CCIC2_CLK_RES_CT=
RL,
+			23, 4, 8, 2, BIT(28), 0);
+CCU_MUX_DIV_GATE_DEFINE(camm1_clk, camm_parents, APMU_CSI_CCIC2_CLK_RES_CT=
RL,
+			23, 4, 8, 2, BIT(6), 0);
+CCU_MUX_DIV_GATE_DEFINE(camm2_clk, camm_parents, APMU_CSI_CCIC2_CLK_RES_CT=
RL,
+			23, 4, 8, 2, BIT(3), 0);
+
+static const struct clk_parent_data isp_cpp_parents[] =3D {
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+};
+CCU_MUX_DIV_GATE_DEFINE(isp_cpp_clk, isp_cpp_parents, APMU_ISP_CLK_RES_CTR=
L, 24,
+			2, 26, 1, BIT(28), 0);
+static const struct clk_parent_data isp_bus_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d10_245p76),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(isp_bus_clk, isp_bus_parents, APMU_ISP_CLK_RES_=
CTRL,
+			   18, 3, BIT(23), 21, 2, BIT(17), 0);
+static const struct clk_parent_data isp_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d8_307p2),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(isp_clk, isp_parents, APMU_ISP_CLK_RES_CTRL, 4,=
 3,
+			   BIT(7), 8, 2, BIT(1), 0);
+
+static const struct clk_parent_data dpumclk_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d8_307p2),
+};
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dpu_mclk, dpumclk_parents,
+				 APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1,
+				 1, 4, BIT(29), 5, 3, BIT(0), 0);
+
+static const struct clk_parent_data dpuesc_parents[] =3D {
+	CCU_PARENT_HW(pll1_d48_51p2_ap),
+	CCU_PARENT_HW(pll1_d52_47p26),
+	CCU_PARENT_HW(pll1_d96_25p6),
+	CCU_PARENT_HW(pll1_d32_76p8),
+};
+CCU_MUX_GATE_DEFINE(dpu_esc_clk, dpuesc_parents, APMU_LCD_CLK_RES_CTRL1, 0=
, 2,
+		    BIT(2), 0);
+
+static const struct clk_parent_data dpubit_parents[] =3D {
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll2_d2),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll2_d5),
+	CCU_PARENT_HW(pll2_d7),
+	CCU_PARENT_HW(pll2_d8),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(dpu_bit_clk, dpubit_parents, APMU_LCD_CLK_RES_C=
TRL1,
+			   17, 3, BIT(31), 20, 3, BIT(16), 0);
+
+static const struct clk_parent_data dpupx_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll2_d7),
+	CCU_PARENT_HW(pll2_d8),
+};
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dpu_pxclk, dpupx_parents,
+				 APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1,
+				 17, 4, BIT(30), 21, 3, BIT(16), 0);
+
+CCU_GATE_DEFINE(dpu_hclk, CCU_PARENT_HW(pmua_aclk), APMU_LCD_CLK_RES_CTRL1,
+		BIT(5), 0);
+
+static const struct clk_parent_data dpu_spi_parents[] =3D {
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d10_245p76),
+	CCU_PARENT_HW(pll1_d11_223p4),
+	CCU_PARENT_HW(pll1_d13_189),
+	CCU_PARENT_HW(pll1_d23_106p8),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d5),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(dpu_spi_clk, dpu_spi_parents,
+			   APMU_LCD_SPI_CLK_RES_CTRL, 8, 3, BIT(7), 12, 3,
+			   BIT(1), 0);
+CCU_GATE_DEFINE(dpu_spi_hbus_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_LCD_SPI_CLK_RES_CTRL, BIT(3), 0);
+CCU_GATE_DEFINE(dpu_spi_bus_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_LCD_SPI_CLK_RES_CTRL, BIT(5), 0);
+CCU_GATE_DEFINE(dpu_spi_aclk, CCU_PARENT_HW(pmua_aclk),
+		APMU_LCD_SPI_CLK_RES_CTRL, BIT(6), 0);
+
+static const struct clk_parent_data v2d_parents[] =3D {
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d4_614p4),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(v2d_clk, v2d_parents, APMU_LCD_CLK_RES_CTRL1, 9=
, 3,
+			   BIT(28), 12, 2, BIT(8), 0);
+
+static const struct clk_parent_data ccic_4x_parents[] =3D {
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll2_d2),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll1_d2_1228p8),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(ccic_4x_clk, ccic_4x_parents, APMU_CCIC_CLK_RES=
_CTRL,
+			   18, 3, BIT(15), 23, 2, BIT(4), 0);
+
+static const struct clk_parent_data ccic1phy_parents[] =3D {
+	CCU_PARENT_HW(pll1_d24_102p4),
+	CCU_PARENT_HW(pll1_d48_51p2_ap),
+};
+CCU_MUX_GATE_DEFINE(ccic1phy_clk, ccic1phy_parents, APMU_CCIC_CLK_RES_CTRL=
, 7,
+		    1, BIT(5), 0);
+
+CCU_GATE_DEFINE(sdh_axi_aclk, CCU_PARENT_HW(pmua_aclk), APMU_SDH0_CLK_RES_=
CTRL,
+		BIT(3), 0);
+static const struct clk_parent_data sdh01_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll2_d8),
+	CCU_PARENT_HW(pll2_d5),
+	CCU_PARENT_HW(pll1_d11_223p4),
+	CCU_PARENT_HW(pll1_d13_189),
+	CCU_PARENT_HW(pll1_d23_106p8),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(sdh0_clk, sdh01_parents, APMU_SDH0_CLK_RES_CTRL=
, 8,
+			   3, BIT(11), 5, 3, BIT(4), 0);
+CCU_MUX_DIV_GATE_FC_DEFINE(sdh1_clk, sdh01_parents, APMU_SDH1_CLK_RES_CTRL=
, 8,
+			   3, BIT(11), 5, 3, BIT(4), 0);
+static const struct clk_parent_data sdh2_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll2_d8),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d11_223p4),
+	CCU_PARENT_HW(pll1_d13_189),
+	CCU_PARENT_HW(pll1_d23_106p8),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(sdh2_clk, sdh2_parents, APMU_SDH2_CLK_RES_CTRL,=
 8, 3,
+			   BIT(11), 5, 3, BIT(4), 0);
+
+CCU_GATE_DEFINE(usb_axi_clk, CCU_PARENT_HW(pmua_aclk), APMU_USB_CLK_RES_CT=
RL,
+		BIT(1), 0);
+CCU_GATE_DEFINE(usb_p1_aclk, CCU_PARENT_HW(pmua_aclk), APMU_USB_CLK_RES_CT=
RL,
+		BIT(5), 0);
+CCU_GATE_DEFINE(usb30_clk, CCU_PARENT_HW(pmua_aclk), APMU_USB_CLK_RES_CTRL,
+		BIT(8), 0);
+
+static const struct clk_parent_data qspi_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll2_d8),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d10_245p76),
+	CCU_PARENT_HW(pll1_d11_223p4),
+	CCU_PARENT_HW(pll1_d23_106p8),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d13_189),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(qspi_clk, qspi_parents, APMU_QSPI_CLK_RES_CTRL,=
 9, 3,
+			   BIT(12), 6, 3, BIT(4), 0);
+CCU_GATE_DEFINE(qspi_bus_clk, CCU_PARENT_HW(pmua_aclk), APMU_QSPI_CLK_RES_=
CTRL,
+		BIT(3), 0);
+CCU_GATE_DEFINE(dma_clk, CCU_PARENT_HW(pmua_aclk), APMU_DMA_CLK_RES_CTRL,
+		BIT(3), 0);
+
+static const struct clk_parent_data aes_parents[] =3D {
+	CCU_PARENT_HW(pll1_d12_204p8),
+	CCU_PARENT_HW(pll1_d24_102p4),
+};
+CCU_MUX_GATE_DEFINE(aes_clk, aes_parents, APMU_AES_CLK_RES_CTRL, 6, 1, BIT=
(5),
+		    0);
+
+static const struct clk_parent_data vpu_parents[] =3D {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll3_d6),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll2_d5),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(vpu_clk, vpu_parents, APMU_VPU_CLK_RES_CTRL, 13=
, 3,
+			   BIT(21), 10, 3, BIT(3), 0);
+
+static const struct clk_parent_data gpu_parents[] =3D {
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d3_819p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll3_d6),
+	CCU_PARENT_HW(pll2_d3),
+	CCU_PARENT_HW(pll2_d4),
+	CCU_PARENT_HW(pll2_d5),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(gpu_clk, gpu_parents, APMU_GPU_CLK_RES_CTRL, 12=
, 3,
+			   BIT(15), 18, 3, BIT(4), 0);
+
+static const struct clk_parent_data emmc_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d52_47p26),
+	CCU_PARENT_HW(pll1_d3_819p2),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(emmc_clk, emmc_parents, APMU_PMUA_EM_CLK_RES_CT=
RL,
+			   8, 3, BIT(11), 6, 2, BIT(4), 0);
+CCU_DIV_GATE_DEFINE(emmc_x_clk, CCU_PARENT_HW(pll1_d2_1228p8),
+		    APMU_PMUA_EM_CLK_RES_CTRL, 12, 3, BIT(15), 0);
+
+static const struct clk_parent_data audio_parents[] =3D {
+	CCU_PARENT_HW(pll1_aud_245p7),
+	CCU_PARENT_HW(pll1_d8_307p2),
+	CCU_PARENT_HW(pll1_d6_409p6),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(audio_clk, audio_parents, APMU_AUDIO_CLK_RES_CT=
RL, 4,
+			   3, BIT(15), 7, 3, BIT(12), 0);
+
+static const struct clk_parent_data hdmi_parents[] =3D {
+	CCU_PARENT_HW(pll1_d6_409p6),
+	CCU_PARENT_HW(pll1_d5_491p52),
+	CCU_PARENT_HW(pll1_d4_614p4),
+	CCU_PARENT_HW(pll1_d8_307p2),
+};
+CCU_MUX_DIV_GATE_FC_DEFINE(hdmi_mclk, hdmi_parents, APMU_HDMI_CLK_RES_CTRL=
, 1,
+			   4, BIT(29), 5, 3, BIT(0), 0);
+
+CCU_GATE_DEFINE(pcie0_master_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_0, BIT(2), 0);
+CCU_GATE_DEFINE(pcie0_slave_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_0, BIT(1), 0);
+CCU_GATE_DEFINE(pcie0_dbi_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_0, BIT(0), 0);
+
+CCU_GATE_DEFINE(pcie1_master_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_1, BIT(2), 0);
+CCU_GATE_DEFINE(pcie1_slave_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_1, BIT(1), 0);
+CCU_GATE_DEFINE(pcie1_dbi_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_1, BIT(0), 0);
+
+CCU_GATE_DEFINE(pcie2_master_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_2, BIT(2), 0);
+CCU_GATE_DEFINE(pcie2_slave_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_2, BIT(1), 0);
+CCU_GATE_DEFINE(pcie2_dbi_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PCIE_CLK_RES_CTRL_2, BIT(0), 0);
+
+CCU_GATE_DEFINE(emac0_bus_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_EMAC0_CLK_RES_CTRL, BIT(0), 0);
+CCU_GATE_DEFINE(emac0_ptp_clk, CCU_PARENT_HW(pll2_d6),
+		APMU_EMAC0_CLK_RES_CTRL, BIT(15), 0);
+CCU_GATE_DEFINE(emac1_bus_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_EMAC1_CLK_RES_CTRL, BIT(0), 0);
+CCU_GATE_DEFINE(emac1_ptp_clk, CCU_PARENT_HW(pll2_d6), APMU_EMAC1_CLK_RES_=
CTRL,
+		BIT(15), 0);
+
+CCU_GATE_DEFINE(emmc_bus_clk, CCU_PARENT_HW(pmua_aclk),
+		APMU_PMUA_EM_CLK_RES_CTRL, BIT(3), 0);
+/* APMU clocks end */
+
+struct spacemit_ccu_data {
+	struct clk_hw **hws;
+	size_t num;
+};
+
+static struct clk_hw *k1_ccu_pll_hws[] =3D {
+	[CLK_PLL1]		=3D &pll1.common.hw,
+	[CLK_PLL2]		=3D &pll2.common.hw,
+	[CLK_PLL3]		=3D &pll3.common.hw,
+	[CLK_PLL1_D2]		=3D &pll1_d2.common.hw,
+	[CLK_PLL1_D3]		=3D &pll1_d3.common.hw,
+	[CLK_PLL1_D4]		=3D &pll1_d4.common.hw,
+	[CLK_PLL1_D5]		=3D &pll1_d5.common.hw,
+	[CLK_PLL1_D6]		=3D &pll1_d6.common.hw,
+	[CLK_PLL1_D7]		=3D &pll1_d7.common.hw,
+	[CLK_PLL1_D8]		=3D &pll1_d8.common.hw,
+	[CLK_PLL1_D11]		=3D &pll1_d11_223p4.common.hw,
+	[CLK_PLL1_D13]		=3D &pll1_d13_189.common.hw,
+	[CLK_PLL1_D23]		=3D &pll1_d23_106p8.common.hw,
+	[CLK_PLL1_D64]		=3D &pll1_d64_38p4.common.hw,
+	[CLK_PLL1_D10_AUD]	=3D &pll1_aud_245p7.common.hw,
+	[CLK_PLL1_D100_AUD]	=3D &pll1_aud_24p5.common.hw,
+	[CLK_PLL2_D1]		=3D &pll2_d1.common.hw,
+	[CLK_PLL2_D2]		=3D &pll2_d2.common.hw,
+	[CLK_PLL2_D3]		=3D &pll2_d3.common.hw,
+	[CLK_PLL2_D4]		=3D &pll2_d4.common.hw,
+	[CLK_PLL2_D5]		=3D &pll2_d5.common.hw,
+	[CLK_PLL2_D6]		=3D &pll2_d6.common.hw,
+	[CLK_PLL2_D7]		=3D &pll2_d7.common.hw,
+	[CLK_PLL2_D8]		=3D &pll2_d8.common.hw,
+	[CLK_PLL3_D1]		=3D &pll3_d1.common.hw,
+	[CLK_PLL3_D2]		=3D &pll3_d2.common.hw,
+	[CLK_PLL3_D3]		=3D &pll3_d3.common.hw,
+	[CLK_PLL3_D4]		=3D &pll3_d4.common.hw,
+	[CLK_PLL3_D5]		=3D &pll3_d5.common.hw,
+	[CLK_PLL3_D6]		=3D &pll3_d6.common.hw,
+	[CLK_PLL3_D7]		=3D &pll3_d7.common.hw,
+	[CLK_PLL3_D8]		=3D &pll3_d8.common.hw,
+	[CLK_PLL3_80]		=3D &pll3_80.common.hw,
+	[CLK_PLL3_40]		=3D &pll3_40.common.hw,
+	[CLK_PLL3_20]		=3D &pll3_20.common.hw,
+};
+
+static const struct spacemit_ccu_data k1_ccu_pll_data =3D {
+	.hws	=3D k1_ccu_pll_hws,
+	.num	=3D ARRAY_SIZE(k1_ccu_pll_hws),
+};
+
+static struct clk_hw *k1_ccu_mpmu_hws[] =3D {
+	[CLK_PLL1_307P2]	=3D &pll1_d8_307p2.common.hw,
+	[CLK_PLL1_76P8]		=3D &pll1_d32_76p8.common.hw,
+	[CLK_PLL1_61P44]	=3D &pll1_d40_61p44.common.hw,
+	[CLK_PLL1_153P6]	=3D &pll1_d16_153p6.common.hw,
+	[CLK_PLL1_102P4]	=3D &pll1_d24_102p4.common.hw,
+	[CLK_PLL1_51P2]		=3D &pll1_d48_51p2.common.hw,
+	[CLK_PLL1_51P2_AP]	=3D &pll1_d48_51p2_ap.common.hw,
+	[CLK_PLL1_57P6]		=3D &pll1_m3d128_57p6.common.hw,
+	[CLK_PLL1_25P6]		=3D &pll1_d96_25p6.common.hw,
+	[CLK_PLL1_12P8]		=3D &pll1_d192_12p8.common.hw,
+	[CLK_PLL1_12P8_WDT]	=3D &pll1_d192_12p8_wdt.common.hw,
+	[CLK_PLL1_6P4]		=3D &pll1_d384_6p4.common.hw,
+	[CLK_PLL1_3P2]		=3D &pll1_d768_3p2.common.hw,
+	[CLK_PLL1_1P6]		=3D &pll1_d1536_1p6.common.hw,
+	[CLK_PLL1_0P8]		=3D &pll1_d3072_0p8.common.hw,
+	[CLK_PLL1_409P6]	=3D &pll1_d6_409p6.common.hw,
+	[CLK_PLL1_204P8]	=3D &pll1_d12_204p8.common.hw,
+	[CLK_PLL1_491]		=3D &pll1_d5_491p52.common.hw,
+	[CLK_PLL1_245P76]	=3D &pll1_d10_245p76.common.hw,
+	[CLK_PLL1_614]		=3D &pll1_d4_614p4.common.hw,
+	[CLK_PLL1_47P26]	=3D &pll1_d52_47p26.common.hw,
+	[CLK_PLL1_31P5]		=3D &pll1_d78_31p5.common.hw,
+	[CLK_PLL1_819]		=3D &pll1_d3_819p2.common.hw,
+	[CLK_PLL1_1228]		=3D &pll1_d2_1228p8.common.hw,
+	[CLK_SLOW_UART]		=3D &slow_uart.common.hw,
+	[CLK_SLOW_UART1]	=3D &slow_uart1_14p74.common.hw,
+	[CLK_SLOW_UART2]	=3D &slow_uart2_48.common.hw,
+	[CLK_WDT]		=3D &wdt_clk.common.hw,
+	[CLK_RIPC]		=3D &ripc_clk.common.hw,
+	[CLK_I2S_SYSCLK]	=3D &i2s_sysclk.common.hw,
+	[CLK_I2S_BCLK]		=3D &i2s_bclk.common.hw,
+	[CLK_APB]		=3D &apb_clk.common.hw,
+	[CLK_WDT_BUS]		=3D &wdt_bus_clk.common.hw,
+};
+
+static const struct spacemit_ccu_data k1_ccu_mpmu_data =3D {
+	.hws	=3D k1_ccu_mpmu_hws,
+	.num	=3D ARRAY_SIZE(k1_ccu_mpmu_hws),
+};
+
+static struct clk_hw *k1_ccu_apbc_hws[] =3D {
+	[CLK_UART0]		=3D &uart0_clk.common.hw,
+	[CLK_UART2]		=3D &uart2_clk.common.hw,
+	[CLK_UART3]		=3D &uart3_clk.common.hw,
+	[CLK_UART4]		=3D &uart4_clk.common.hw,
+	[CLK_UART5]		=3D &uart5_clk.common.hw,
+	[CLK_UART6]		=3D &uart6_clk.common.hw,
+	[CLK_UART7]		=3D &uart7_clk.common.hw,
+	[CLK_UART8]		=3D &uart8_clk.common.hw,
+	[CLK_UART9]		=3D &uart9_clk.common.hw,
+	[CLK_GPIO]		=3D &gpio_clk.common.hw,
+	[CLK_PWM0]		=3D &pwm0_clk.common.hw,
+	[CLK_PWM1]		=3D &pwm1_clk.common.hw,
+	[CLK_PWM2]		=3D &pwm2_clk.common.hw,
+	[CLK_PWM3]		=3D &pwm3_clk.common.hw,
+	[CLK_PWM4]		=3D &pwm4_clk.common.hw,
+	[CLK_PWM5]		=3D &pwm5_clk.common.hw,
+	[CLK_PWM6]		=3D &pwm6_clk.common.hw,
+	[CLK_PWM7]		=3D &pwm7_clk.common.hw,
+	[CLK_PWM8]		=3D &pwm8_clk.common.hw,
+	[CLK_PWM9]		=3D &pwm9_clk.common.hw,
+	[CLK_PWM10]		=3D &pwm10_clk.common.hw,
+	[CLK_PWM11]		=3D &pwm11_clk.common.hw,
+	[CLK_PWM12]		=3D &pwm12_clk.common.hw,
+	[CLK_PWM13]		=3D &pwm13_clk.common.hw,
+	[CLK_PWM14]		=3D &pwm14_clk.common.hw,
+	[CLK_PWM15]		=3D &pwm15_clk.common.hw,
+	[CLK_PWM16]		=3D &pwm16_clk.common.hw,
+	[CLK_PWM17]		=3D &pwm17_clk.common.hw,
+	[CLK_PWM18]		=3D &pwm18_clk.common.hw,
+	[CLK_PWM19]		=3D &pwm19_clk.common.hw,
+	[CLK_SSP3]		=3D &ssp3_clk.common.hw,
+	[CLK_RTC]		=3D &rtc_clk.common.hw,
+	[CLK_TWSI0]		=3D &twsi0_clk.common.hw,
+	[CLK_TWSI1]		=3D &twsi1_clk.common.hw,
+	[CLK_TWSI2]		=3D &twsi2_clk.common.hw,
+	[CLK_TWSI4]		=3D &twsi4_clk.common.hw,
+	[CLK_TWSI5]		=3D &twsi5_clk.common.hw,
+	[CLK_TWSI6]		=3D &twsi6_clk.common.hw,
+	[CLK_TWSI7]		=3D &twsi7_clk.common.hw,
+	[CLK_TIMERS1]		=3D &timers1_clk.common.hw,
+	[CLK_TIMERS2]		=3D &timers2_clk.common.hw,
+	[CLK_AIB]		=3D &aib_clk.common.hw,
+	[CLK_ONEWIRE]		=3D &onewire_clk.common.hw,
+	[CLK_SSPA0]		=3D &sspa0_clk.common.hw,
+	[CLK_SSPA1]		=3D &sspa1_clk.common.hw,
+	[CLK_DRO]		=3D &dro_clk.common.hw,
+	[CLK_IR]		=3D &ir_clk.common.hw,
+	[CLK_TSEN]		=3D &tsen_clk.common.hw,
+	[CLK_IPC_AP2AUD]	=3D &ipc_ap2aud_clk.common.hw,
+	[CLK_CAN0]		=3D &can0_clk.common.hw,
+	[CLK_CAN0_BUS]		=3D &can0_bus_clk.common.hw,
+	[CLK_UART0_BUS]		=3D &uart0_bus_clk.common.hw,
+	[CLK_UART2_BUS]		=3D &uart2_bus_clk.common.hw,
+	[CLK_UART3_BUS]		=3D &uart3_bus_clk.common.hw,
+	[CLK_UART4_BUS]		=3D &uart4_bus_clk.common.hw,
+	[CLK_UART5_BUS]		=3D &uart5_bus_clk.common.hw,
+	[CLK_UART6_BUS]		=3D &uart6_bus_clk.common.hw,
+	[CLK_UART7_BUS]		=3D &uart7_bus_clk.common.hw,
+	[CLK_UART8_BUS]		=3D &uart8_bus_clk.common.hw,
+	[CLK_UART9_BUS]		=3D &uart9_bus_clk.common.hw,
+	[CLK_GPIO_BUS]		=3D &gpio_bus_clk.common.hw,
+	[CLK_PWM0_BUS]		=3D &pwm0_bus_clk.common.hw,
+	[CLK_PWM1_BUS]		=3D &pwm1_bus_clk.common.hw,
+	[CLK_PWM2_BUS]		=3D &pwm2_bus_clk.common.hw,
+	[CLK_PWM3_BUS]		=3D &pwm3_bus_clk.common.hw,
+	[CLK_PWM4_BUS]		=3D &pwm4_bus_clk.common.hw,
+	[CLK_PWM5_BUS]		=3D &pwm5_bus_clk.common.hw,
+	[CLK_PWM6_BUS]		=3D &pwm6_bus_clk.common.hw,
+	[CLK_PWM7_BUS]		=3D &pwm7_bus_clk.common.hw,
+	[CLK_PWM8_BUS]		=3D &pwm8_bus_clk.common.hw,
+	[CLK_PWM9_BUS]		=3D &pwm9_bus_clk.common.hw,
+	[CLK_PWM10_BUS]		=3D &pwm10_bus_clk.common.hw,
+	[CLK_PWM11_BUS]		=3D &pwm11_bus_clk.common.hw,
+	[CLK_PWM12_BUS]		=3D &pwm12_bus_clk.common.hw,
+	[CLK_PWM13_BUS]		=3D &pwm13_bus_clk.common.hw,
+	[CLK_PWM14_BUS]		=3D &pwm14_bus_clk.common.hw,
+	[CLK_PWM15_BUS]		=3D &pwm15_bus_clk.common.hw,
+	[CLK_PWM16_BUS]		=3D &pwm16_bus_clk.common.hw,
+	[CLK_PWM17_BUS]		=3D &pwm17_bus_clk.common.hw,
+	[CLK_PWM18_BUS]		=3D &pwm18_bus_clk.common.hw,
+	[CLK_PWM19_BUS]		=3D &pwm19_bus_clk.common.hw,
+	[CLK_SSP3_BUS]		=3D &ssp3_bus_clk.common.hw,
+	[CLK_RTC_BUS]		=3D &rtc_bus_clk.common.hw,
+	[CLK_TWSI0_BUS]		=3D &twsi0_bus_clk.common.hw,
+	[CLK_TWSI1_BUS]		=3D &twsi1_bus_clk.common.hw,
+	[CLK_TWSI2_BUS]		=3D &twsi2_bus_clk.common.hw,
+	[CLK_TWSI4_BUS]		=3D &twsi4_bus_clk.common.hw,
+	[CLK_TWSI5_BUS]		=3D &twsi5_bus_clk.common.hw,
+	[CLK_TWSI6_BUS]		=3D &twsi6_bus_clk.common.hw,
+	[CLK_TWSI7_BUS]		=3D &twsi7_bus_clk.common.hw,
+	[CLK_TIMERS1_BUS]	=3D &timers1_bus_clk.common.hw,
+	[CLK_TIMERS2_BUS]	=3D &timers2_bus_clk.common.hw,
+	[CLK_AIB_BUS]		=3D &aib_bus_clk.common.hw,
+	[CLK_ONEWIRE_BUS]	=3D &onewire_bus_clk.common.hw,
+	[CLK_SSPA0_BUS]		=3D &sspa0_bus_clk.common.hw,
+	[CLK_SSPA1_BUS]		=3D &sspa1_bus_clk.common.hw,
+	[CLK_TSEN_BUS]		=3D &tsen_bus_clk.common.hw,
+	[CLK_IPC_AP2AUD_BUS]	=3D &ipc_ap2aud_bus_clk.common.hw,
+};
+
+static const struct spacemit_ccu_data k1_ccu_apbc_data =3D {
+	.hws	=3D k1_ccu_apbc_hws,
+	.num	=3D ARRAY_SIZE(k1_ccu_apbc_hws),
+};
+
+static struct clk_hw *k1_ccu_apmu_hws[] =3D {
+	[CLK_CCI550]		=3D &cci550_clk.common.hw,
+	[CLK_CPU_C0_HI]		=3D &cpu_c0_hi_clk.common.hw,
+	[CLK_CPU_C0_CORE]	=3D &cpu_c0_core_clk.common.hw,
+	[CLK_CPU_C0_ACE]	=3D &cpu_c0_ace_clk.common.hw,
+	[CLK_CPU_C0_TCM]	=3D &cpu_c0_tcm_clk.common.hw,
+	[CLK_CPU_C1_HI]		=3D &cpu_c1_hi_clk.common.hw,
+	[CLK_CPU_C1_CORE]	=3D &cpu_c1_core_clk.common.hw,
+	[CLK_CPU_C1_ACE]	=3D &cpu_c1_ace_clk.common.hw,
+	[CLK_CCIC_4X]		=3D &ccic_4x_clk.common.hw,
+	[CLK_CCIC1PHY]		=3D &ccic1phy_clk.common.hw,
+	[CLK_SDH_AXI]		=3D &sdh_axi_aclk.common.hw,
+	[CLK_SDH0]		=3D &sdh0_clk.common.hw,
+	[CLK_SDH1]		=3D &sdh1_clk.common.hw,
+	[CLK_SDH2]		=3D &sdh2_clk.common.hw,
+	[CLK_USB_P1]		=3D &usb_p1_aclk.common.hw,
+	[CLK_USB_AXI]		=3D &usb_axi_clk.common.hw,
+	[CLK_USB30]		=3D &usb30_clk.common.hw,
+	[CLK_QSPI]		=3D &qspi_clk.common.hw,
+	[CLK_QSPI_BUS]		=3D &qspi_bus_clk.common.hw,
+	[CLK_DMA]		=3D &dma_clk.common.hw,
+	[CLK_AES]		=3D &aes_clk.common.hw,
+	[CLK_VPU]		=3D &vpu_clk.common.hw,
+	[CLK_GPU]		=3D &gpu_clk.common.hw,
+	[CLK_EMMC]		=3D &emmc_clk.common.hw,
+	[CLK_EMMC_X]		=3D &emmc_x_clk.common.hw,
+	[CLK_AUDIO]		=3D &audio_clk.common.hw,
+	[CLK_HDMI]		=3D &hdmi_mclk.common.hw,
+	[CLK_PMUA_ACLK]		=3D &pmua_aclk.common.hw,
+	[CLK_PCIE0_MASTER]	=3D &pcie0_master_clk.common.hw,
+	[CLK_PCIE0_SLAVE]	=3D &pcie0_slave_clk.common.hw,
+	[CLK_PCIE0_DBI]		=3D &pcie0_dbi_clk.common.hw,
+	[CLK_PCIE1_MASTER]	=3D &pcie1_master_clk.common.hw,
+	[CLK_PCIE1_SLAVE]	=3D &pcie1_slave_clk.common.hw,
+	[CLK_PCIE1_DBI]		=3D &pcie1_dbi_clk.common.hw,
+	[CLK_PCIE2_MASTER]	=3D &pcie2_master_clk.common.hw,
+	[CLK_PCIE2_SLAVE]	=3D &pcie2_slave_clk.common.hw,
+	[CLK_PCIE2_DBI]		=3D &pcie2_dbi_clk.common.hw,
+	[CLK_EMAC0_BUS]		=3D &emac0_bus_clk.common.hw,
+	[CLK_EMAC0_PTP]		=3D &emac0_ptp_clk.common.hw,
+	[CLK_EMAC1_BUS]		=3D &emac1_bus_clk.common.hw,
+	[CLK_EMAC1_PTP]		=3D &emac1_ptp_clk.common.hw,
+	[CLK_JPG]		=3D &jpg_clk.common.hw,
+	[CLK_CCIC2PHY]		=3D &ccic2phy_clk.common.hw,
+	[CLK_CCIC3PHY]		=3D &ccic3phy_clk.common.hw,
+	[CLK_CSI]		=3D &csi_clk.common.hw,
+	[CLK_CAMM0]		=3D &camm0_clk.common.hw,
+	[CLK_CAMM1]		=3D &camm1_clk.common.hw,
+	[CLK_CAMM2]		=3D &camm2_clk.common.hw,
+	[CLK_ISP_CPP]		=3D &isp_cpp_clk.common.hw,
+	[CLK_ISP_BUS]		=3D &isp_bus_clk.common.hw,
+	[CLK_ISP]		=3D &isp_clk.common.hw,
+	[CLK_DPU_MCLK]		=3D &dpu_mclk.common.hw,
+	[CLK_DPU_ESC]		=3D &dpu_esc_clk.common.hw,
+	[CLK_DPU_BIT]		=3D &dpu_bit_clk.common.hw,
+	[CLK_DPU_PXCLK]		=3D &dpu_pxclk.common.hw,
+	[CLK_DPU_HCLK]		=3D &dpu_hclk.common.hw,
+	[CLK_DPU_SPI]		=3D &dpu_spi_clk.common.hw,
+	[CLK_DPU_SPI_HBUS]	=3D &dpu_spi_hbus_clk.common.hw,
+	[CLK_DPU_SPIBUS]	=3D &dpu_spi_bus_clk.common.hw,
+	[CLK_DPU_SPI_ACLK]	=3D &dpu_spi_aclk.common.hw,
+	[CLK_V2D]		=3D &v2d_clk.common.hw,
+	[CLK_EMMC_BUS]		=3D &emmc_bus_clk.common.hw,
+};
+
+static const struct spacemit_ccu_data k1_ccu_apmu_data =3D {
+	.hws	=3D k1_ccu_apmu_hws,
+	.num	=3D ARRAY_SIZE(k1_ccu_apmu_hws),
+};
+
+static int spacemit_ccu_register(struct device *dev,
+				 struct regmap *regmap, struct regmap *lock_regmap,
+				 const struct spacemit_ccu_data *data)
+{
+	struct clk_hw_onecell_data *clk_data;
+	int i, ret;
+
+	clk_data =3D devm_kzalloc(dev, struct_size(clk_data, hws, data->num),
+				GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	for (i =3D 0; i < data->num; i++) {
+		struct clk_hw *hw =3D data->hws[i];
+		struct ccu_common *common;
+		const char *name;
+
+		if (!hw) {
+			clk_data->hws[i] =3D ERR_PTR(-ENOENT);
+			continue;
+		}
+
+		name =3D hw->init->name;
+
+		common =3D hw_to_ccu_common(hw);
+		common->regmap		=3D regmap;
+		common->lock_regmap	=3D lock_regmap;
+
+		ret =3D devm_clk_hw_register(dev, hw);
+		if (ret) {
+			dev_err(dev, "Cannot register clock %d - %s\n",
+				i, name);
+			return ret;
+		}
+
+		clk_data->hws[i] =3D hw;
+	}
+
+	clk_data->num =3D data->num;
+
+	ret =3D devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
+	if (ret)
+		dev_err(dev, "failed to add clock hardware provider (%d)\n", ret);
+
+	return ret;
+}
+
+static int k1_ccu_probe(struct platform_device *pdev)
+{
+	struct regmap *base_regmap, *lock_regmap =3D NULL;
+	struct device *dev =3D &pdev->dev;
+	int ret;
+
+	base_regmap =3D device_node_to_regmap(dev->of_node);
+	if (IS_ERR(base_regmap))
+		return dev_err_probe(dev, PTR_ERR(base_regmap),
+				     "failed to get regmap\n");
+
+	/*
+	 * The lock status of PLLs locate in MPMU region, while PLLs themselves
+	 * are in APBS region. Reference to MPMU syscon is required to check PLL
+	 * status.
+	 */
+	if (of_device_is_compatible(dev->of_node, "spacemit,k1-pll")) {
+		struct device_node *mpmu =3D of_parse_phandle(dev->of_node,
+							    "spacemit,mpmu", 0);
+		if (!mpmu)
+			return dev_err_probe(dev, -ENODEV,
+					     "Cannot parse MPMU region\n");
+
+		lock_regmap =3D device_node_to_regmap(mpmu);
+		of_node_put(mpmu);
+
+		if (IS_ERR(lock_regmap))
+			return dev_err_probe(dev, PTR_ERR(lock_regmap),
+					     "failed to get lock regmap\n");
+	}
+
+	ret =3D spacemit_ccu_register(dev, base_regmap, lock_regmap,
+				    of_device_get_match_data(dev));
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register clocks\n");
+
+	return 0;
+}
+
+static const struct of_device_id of_k1_ccu_match[] =3D {
+	{
+		.compatible	=3D "spacemit,k1-pll",
+		.data		=3D &k1_ccu_pll_data,
+	},
+	{
+		.compatible	=3D "spacemit,k1-syscon-mpmu",
+		.data		=3D &k1_ccu_mpmu_data,
+	},
+	{
+		.compatible	=3D "spacemit,k1-syscon-apbc",
+		.data		=3D &k1_ccu_apbc_data,
+	},
+	{
+		.compatible	=3D "spacemit,k1-syscon-apmu",
+		.data		=3D &k1_ccu_apmu_data,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, of_k1_ccu_match);
+
+static struct platform_driver k1_ccu_driver =3D {
+	.driver =3D {
+		.name		=3D "spacemit,k1-ccu",
+		.of_match_table =3D of_k1_ccu_match,
+	},
+	.probe	=3D k1_ccu_probe,
+};
+module_platform_driver(k1_ccu_driver);
+
+MODULE_DESCRIPTION("SpacemiT K1 CCU driver");
+MODULE_AUTHOR("Haylen Chu <heylenay@4d2.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_c=
ommon.h
new file mode 100644
index 000000000000..f1a584b44486
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_common.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org>
+ */
+
+#ifndef _CCU_COMMON_H_
+#define _CCU_COMMON_H_
+
+#include <linux/regmap.h>
+
+struct ccu_common {
+	struct regmap *regmap;
+	struct regmap *lock_regmap;
+
+	union {
+		/* For DDN and MIX */
+		struct {
+			u32 reg_ctrl;
+			u32 reg_fc;
+			u32 mask_fc;
+		};
+
+		/* For PLL */
+		struct {
+			u32 reg_swcr1;
+			u32 reg_swcr3;
+		};
+	};
+
+	struct clk_hw hw;
+};
+
+static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw)
+{
+	return container_of(hw, struct ccu_common, hw);
+}
+
+#define ccu_read(c, reg)						\
+	({								\
+		u32 tmp;						\
+		regmap_read((c)->regmap, (c)->reg_##reg, &tmp);		\
+		tmp;							\
+	 })
+#define ccu_update(c, reg, mask, val) \
+	regmap_update_bits((c)->regmap, (c)->reg_##reg, mask, val)
+
+#endif /* _CCU_COMMON_H_ */
diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c
new file mode 100644
index 000000000000..118f5652df26
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_ddn.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org>
+ *
+ * DDN stands for "Divider Denominator Numerator", it's M/N clock with a
+ * constant x2 factor. This clock hardware follows the equation below,
+ *
+ *	      numerator       Fin
+ *	2 * ------------- =3D -------
+ *	     denominator      Fout
+ *
+ * Thus, Fout could be calculated with,
+ *
+ *		Fin	denominator
+ *	Fout =3D ----- * -------------
+ *		 2	 numerator
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/rational.h>
+
+#include "ccu_ddn.h"
+
+static unsigned long ccu_ddn_calc_rate(unsigned long prate,
+				       unsigned long num, unsigned long den)
+{
+	return prate * den / 2 / num;
+}
+
+static unsigned long ccu_ddn_calc_best_rate(struct ccu_ddn *ddn,
+					    unsigned long rate, unsigned long prate,
+					    unsigned long *num, unsigned long *den)
+{
+	rational_best_approximation(rate, prate / 2,
+				    ddn->den_mask >> ddn->den_shift,
+				    ddn->num_mask >> ddn->num_shift,
+				    den, num);
+	return ccu_ddn_calc_rate(prate, *num, *den);
+}
+
+static long ccu_ddn_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *prate)
+{
+	struct ccu_ddn *ddn =3D hw_to_ccu_ddn(hw);
+	unsigned long num, den;
+
+	return ccu_ddn_calc_best_rate(ddn, rate, *prate, &num, &den);
+}
+
+static unsigned long ccu_ddn_recalc_rate(struct clk_hw *hw, unsigned long =
prate)
+{
+	struct ccu_ddn *ddn =3D hw_to_ccu_ddn(hw);
+	unsigned int val, num, den;
+
+	val =3D ccu_read(&ddn->common, ctrl);
+
+	num =3D (val & ddn->num_mask) >> ddn->num_shift;
+	den =3D (val & ddn->den_mask) >> ddn->den_shift;
+
+	return ccu_ddn_calc_rate(prate, num, den);
+}
+
+static int ccu_ddn_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long prate)
+{
+	struct ccu_ddn *ddn =3D hw_to_ccu_ddn(hw);
+	unsigned long num, den;
+
+	ccu_ddn_calc_best_rate(ddn, rate, prate, &num, &den);
+
+	ccu_update(&ddn->common, ctrl,
+		   ddn->num_mask | ddn->den_mask,
+		   (num << ddn->num_shift) | (den << ddn->den_shift));
+
+	return 0;
+}
+
+const struct clk_ops spacemit_ccu_ddn_ops =3D {
+	.recalc_rate	=3D ccu_ddn_recalc_rate,
+	.round_rate	=3D ccu_ddn_round_rate,
+	.set_rate	=3D ccu_ddn_set_rate,
+};
diff --git a/drivers/clk/spacemit/ccu_ddn.h b/drivers/clk/spacemit/ccu_ddn.h
new file mode 100644
index 000000000000..60fa7c729f9a
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_ddn.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org>
+ */
+
+#ifndef _CCU_DDN_H_
+#define _CCU_DDN_H_
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+struct ccu_ddn {
+	struct ccu_common common;
+	unsigned int num_mask;
+	unsigned int num_shift;
+	unsigned int den_mask;
+	unsigned int den_shift;
+};
+
+#define CCU_DDN_INIT(_name, _parent, _flags) \
+	CLK_HW_INIT_HW(#_name, &_parent.common.hw, &spacemit_ccu_ddn_ops, _flags)
+
+#define CCU_DDN_DEFINE(_name, _parent, _reg_ctrl, _num_mask, _den_mask, _f=
lags)	\
+static struct ccu_ddn _name =3D {							\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		.hw.init	=3D CCU_DDN_INIT(_name, _parent, _flags),		\
+	},									\
+	.num_mask	=3D _num_mask,						\
+	.num_shift	=3D __ffs(_num_mask),					\
+	.den_mask	=3D _den_mask,						\
+	.den_shift	=3D __ffs(_den_mask),					\
+}
+
+static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw)
+{
+	struct ccu_common *common =3D hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_ddn, common);
+}
+
+extern const struct clk_ops spacemit_ccu_ddn_ops;
+
+#endif
diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c
new file mode 100644
index 000000000000..2b43c4ea0881
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_mix.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org>
+ *
+ * MIX clock type is the combination of mux, factor or divider, and gate
+ */
+
+#include <linux/clk-provider.h>
+
+#include "ccu_mix.h"
+
+#define MIX_FC_TIMEOUT_US	10000
+#define MIX_FC_DELAY_US		5
+
+static void ccu_gate_disable(struct clk_hw *hw)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+
+	ccu_update(&mix->common, ctrl, mix->gate.mask, 0);
+}
+
+static int ccu_gate_enable(struct clk_hw *hw)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+	struct ccu_gate_config *gate =3D &mix->gate;
+
+	ccu_update(&mix->common, ctrl, gate->mask, gate->mask);
+
+	return 0;
+}
+
+static int ccu_gate_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+	struct ccu_gate_config *gate =3D &mix->gate;
+
+	return (ccu_read(&mix->common, ctrl) & gate->mask) =3D=3D gate->mask;
+}
+
+static unsigned long ccu_factor_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+
+	return parent_rate * mix->factor.mul / mix->factor.div;
+}
+
+static unsigned long ccu_div_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+	struct ccu_div_config *div =3D &mix->div;
+	unsigned long val;
+
+	val =3D ccu_read(&mix->common, ctrl) >> div->shift;
+	val &=3D (1 << div->width) - 1;
+
+	return divider_recalc_rate(hw, parent_rate, val, NULL, 0, div->width);
+}
+
+/*
+ * Some clocks require a "FC" (frequency change) bit to be set after chang=
ing
+ * their rates or reparenting. This bit will be automatically cleared by
+ * hardware in MIX_FC_TIMEOUT_US, which indicates the operation is complet=
ed.
+ */
+static int ccu_mix_trigger_fc(struct clk_hw *hw)
+{
+	struct ccu_common *common =3D hw_to_ccu_common(hw);
+	unsigned int val;
+
+	if (common->reg_fc)
+		return 0;
+
+	ccu_update(common, fc, common->mask_fc, common->mask_fc);
+
+	return regmap_read_poll_timeout_atomic(common->regmap, common->reg_fc,
+					       val, !(val & common->mask_fc),
+					       MIX_FC_DELAY_US,
+					       MIX_FC_TIMEOUT_US);
+}
+
+static long ccu_factor_round_rate(struct clk_hw *hw, unsigned long rate,
+				  unsigned long *prate)
+{
+	return ccu_factor_recalc_rate(hw, *prate);
+}
+
+static int ccu_factor_set_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long parent_rate)
+{
+	return 0;
+}
+
+static unsigned long
+ccu_mix_calc_best_rate(struct clk_hw *hw, unsigned long rate,
+		       struct clk_hw **best_parent,
+		       unsigned long *best_parent_rate,
+		       u32 *div_val)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+	unsigned int parent_num =3D clk_hw_get_num_parents(hw);
+	struct ccu_div_config *div =3D &mix->div;
+	u32 div_max =3D 1 << div->width;
+	unsigned long best_rate =3D 0;
+
+	for (int i =3D 0; i < parent_num; i++) {
+		struct clk_hw *parent =3D clk_hw_get_parent_by_index(hw, i);
+		unsigned long parent_rate;
+
+		if (!parent)
+			continue;
+
+		parent_rate =3D clk_hw_get_rate(parent);
+
+		for (int j =3D 1; j <=3D div_max; j++) {
+			unsigned long tmp =3D DIV_ROUND_CLOSEST_ULL(parent_rate, j);
+
+			if (abs(tmp - rate) < abs(best_rate - rate)) {
+				best_rate =3D tmp;
+
+				if (div_val)
+					*div_val =3D j - 1;
+
+				if (best_parent) {
+					*best_parent      =3D parent;
+					*best_parent_rate =3D parent_rate;
+				}
+			}
+		}
+	}
+
+	return best_rate;
+}
+
+static int ccu_mix_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	req->rate =3D ccu_mix_calc_best_rate(hw, req->rate,
+					   &req->best_parent_hw,
+					   &req->best_parent_rate,
+					   NULL);
+	return 0;
+}
+
+static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+	struct ccu_common *common =3D &mix->common;
+	struct ccu_div_config *div =3D &mix->div;
+	u32 current_div, target_div, mask;
+
+	ccu_mix_calc_best_rate(hw, rate, NULL, NULL, &target_div);
+
+	current_div =3D ccu_read(common, ctrl) >> div->shift;
+	current_div &=3D (1 << div->width) - 1;
+
+	if (current_div =3D=3D target_div)
+		return 0;
+
+	mask =3D GENMASK(div->width + div->shift - 1, div->shift);
+
+	ccu_update(common, ctrl, mask, target_div << div->shift);
+
+	return ccu_mix_trigger_fc(hw);
+}
+
+static u8 ccu_mux_get_parent(struct clk_hw *hw)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+	struct ccu_mux_config *mux =3D &mix->mux;
+	u8 parent;
+
+	parent =3D ccu_read(&mix->common, ctrl) >> mux->shift;
+	parent &=3D (1 << mux->width) - 1;
+
+	return parent;
+}
+
+static int ccu_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct ccu_mix *mix =3D hw_to_ccu_mix(hw);
+	struct ccu_mux_config *mux =3D &mix->mux;
+	u32 mask;
+
+	mask =3D GENMASK(mux->width + mux->shift - 1, mux->shift);
+
+	ccu_update(&mix->common, ctrl, mask, index << mux->shift);
+
+	return ccu_mix_trigger_fc(hw);
+}
+
+const struct clk_ops spacemit_ccu_gate_ops =3D {
+	.disable	=3D ccu_gate_disable,
+	.enable		=3D ccu_gate_enable,
+	.is_enabled	=3D ccu_gate_is_enabled,
+};
+
+const struct clk_ops spacemit_ccu_factor_ops =3D {
+	.round_rate	=3D ccu_factor_round_rate,
+	.recalc_rate	=3D ccu_factor_recalc_rate,
+	.set_rate	=3D ccu_factor_set_rate,
+};
+
+const struct clk_ops spacemit_ccu_mux_ops =3D {
+	.determine_rate =3D ccu_mix_determine_rate,
+	.get_parent	=3D ccu_mux_get_parent,
+	.set_parent	=3D ccu_mux_set_parent,
+};
+
+const struct clk_ops spacemit_ccu_div_ops =3D {
+	.determine_rate =3D ccu_mix_determine_rate,
+	.recalc_rate	=3D ccu_div_recalc_rate,
+	.set_rate	=3D ccu_mix_set_rate,
+};
+
+const struct clk_ops spacemit_ccu_factor_gate_ops =3D {
+	.disable	=3D ccu_gate_disable,
+	.enable		=3D ccu_gate_enable,
+	.is_enabled	=3D ccu_gate_is_enabled,
+
+	.round_rate	=3D ccu_factor_round_rate,
+	.recalc_rate	=3D ccu_factor_recalc_rate,
+	.set_rate	=3D ccu_factor_set_rate,
+};
+
+const struct clk_ops spacemit_ccu_mux_gate_ops =3D {
+	.disable	=3D ccu_gate_disable,
+	.enable		=3D ccu_gate_enable,
+	.is_enabled	=3D ccu_gate_is_enabled,
+
+	.determine_rate =3D ccu_mix_determine_rate,
+	.get_parent	=3D ccu_mux_get_parent,
+	.set_parent	=3D ccu_mux_set_parent,
+};
+
+const struct clk_ops spacemit_ccu_div_gate_ops =3D {
+	.disable	=3D ccu_gate_disable,
+	.enable		=3D ccu_gate_enable,
+	.is_enabled	=3D ccu_gate_is_enabled,
+
+	.determine_rate =3D ccu_mix_determine_rate,
+	.recalc_rate	=3D ccu_div_recalc_rate,
+	.set_rate	=3D ccu_mix_set_rate,
+};
+
+const struct clk_ops spacemit_ccu_mux_div_gate_ops =3D {
+	.disable	=3D ccu_gate_disable,
+	.enable		=3D ccu_gate_enable,
+	.is_enabled	=3D ccu_gate_is_enabled,
+
+	.get_parent	=3D ccu_mux_get_parent,
+	.set_parent	=3D ccu_mux_set_parent,
+
+	.determine_rate =3D ccu_mix_determine_rate,
+	.recalc_rate	=3D ccu_div_recalc_rate,
+	.set_rate	=3D ccu_mix_set_rate,
+};
+
+const struct clk_ops spacemit_ccu_mux_div_ops =3D {
+	.get_parent	=3D ccu_mux_get_parent,
+	.set_parent	=3D ccu_mux_set_parent,
+
+	.determine_rate =3D ccu_mix_determine_rate,
+	.recalc_rate	=3D ccu_div_recalc_rate,
+	.set_rate	=3D ccu_mix_set_rate,
+};
diff --git a/drivers/clk/spacemit/ccu_mix.h b/drivers/clk/spacemit/ccu_mix.h
new file mode 100644
index 000000000000..eb19c43bea5f
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_mix.h
@@ -0,0 +1,218 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org>
+ */
+
+#ifndef _CCU_MIX_H_
+#define _CCU_MIX_H_
+
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+/**
+ * struct ccu_gate_config - Gate configuration
+ *
+ * @mask:	Mask to enable the gate. Some clocks may have more than one bit
+ *		set in this field.
+ */
+struct ccu_gate_config {
+	u32 mask;
+};
+
+struct ccu_factor_config {
+	u32 div;
+	u32 mul;
+};
+
+struct ccu_mux_config {
+	u8 shift;
+	u8 width;
+};
+
+struct ccu_div_config {
+	u8 shift;
+	u8 width;
+};
+
+struct ccu_mix {
+	struct ccu_factor_config factor;
+	struct ccu_gate_config gate;
+	struct ccu_div_config div;
+	struct ccu_mux_config mux;
+	struct ccu_common common;
+};
+
+#define CCU_GATE_INIT(_mask)		{ .mask =3D _mask }
+#define CCU_FACTOR_INIT(_div, _mul)	{ .div =3D _div, .mul =3D _mul }
+#define CCU_MUX_INIT(_shift, _width)	{ .shift =3D _shift, .width =3D _widt=
h }
+#define CCU_DIV_INIT(_shift, _width)	{ .shift =3D _shift, .width =3D _widt=
h }
+
+#define CCU_PARENT_HW(_parent)		{ .hw =3D &_parent.common.hw }
+#define CCU_PARENT_NAME(_name)		{ .fw_name =3D #_name }
+
+#define CCU_MIX_INITHW(_name, _parent, _ops, _flags)			\
+	.hw.init =3D &(struct clk_init_data) {				\
+		.flags		=3D _flags,				\
+		.name		=3D #_name,				\
+		.parent_data	=3D (const struct clk_parent_data[])	\
+					{ _parent },			\
+		.num_parents	=3D 1,					\
+		.ops		=3D &_ops,				\
+	}
+
+#define CCU_MIX_INITHW_PARENTS(_name, _parents, _ops, _flags)		\
+	.hw.init =3D CLK_HW_INIT_PARENTS_DATA(#_name, _parents, &_ops, _flags)
+
+#define CCU_GATE_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _flags)		\
+static struct ccu_mix _name =3D {							\
+	.gate	=3D CCU_GATE_INIT(_mask_gate),					\
+	.common	=3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_gate_ops, _flags),	\
+	}									\
+}
+
+#define CCU_FACTOR_DEFINE(_name, _parent, _div, _mul)				\
+static struct ccu_mix _name =3D {							\
+	.factor	=3D CCU_FACTOR_INIT(_div, _mul),					\
+	.common =3D {								\
+		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_factor_ops, 0),	\
+	}									\
+}
+
+#define CCU_MUX_DEFINE(_name, _parents, _reg_ctrl, _shift, _width, _flags)=
	\
+static struct ccu_mix _name =3D {							\
+	.mux	=3D CCU_MUX_INIT(_shift, _width),					\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		CCU_MIX_INITHW_PARENTS(_name, _parents, spacemit_ccu_mux_ops,	\
+				       _flags),					\
+	}									\
+}
+
+#define CCU_DIV_DEFINE(_name, _parent, _reg_ctrl, _shift, _width, _flags)	\
+static struct ccu_mix _name =3D {							\
+	.div	=3D CCU_DIV_INIT(_shift, _width),					\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_div_ops, _flags)	\
+	}									\
+}
+
+#define CCU_FACTOR_GATE_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div=
,	\
+			       _mul)						\
+static struct ccu_mix _name =3D {							\
+	.gate	=3D CCU_GATE_INIT(_mask_gate),					\
+	.factor	=3D CCU_FACTOR_INIT(_div, _mul),					\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_factor_gate_ops, 0)	\
+	}									\
+}
+
+#define CCU_MUX_GATE_DEFINE(_name, _parents, _reg_ctrl, _shift, _width,		\
+			    _mask_gate, _flags)					\
+static struct ccu_mix _name =3D {							\
+	.gate	=3D CCU_GATE_INIT(_mask_gate),					\
+	.mux	=3D CCU_MUX_INIT(_shift, _width),					\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		CCU_MIX_INITHW_PARENTS(_name, _parents,				\
+				       spacemit_ccu_mux_gate_ops, _flags),	\
+	}									\
+}
+
+#define CCU_DIV_GATE_DEFINE(_name, _parent, _reg_ctrl, _shift, _width,		\
+			    _mask_gate,	_flags)					\
+static struct ccu_mix _name =3D {							\
+	.gate	=3D CCU_GATE_INIT(_mask_gate),					\
+	.div	=3D CCU_DIV_INIT(_shift, _width),					\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		CCU_MIX_INITHW(_name, _parent, spacemit_ccu_div_gate_ops,	\
+			       _flags),						\
+	}									\
+}
+
+#define CCU_MUX_DIV_GATE_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwid=
th,	\
+				 _muxshift, _muxwidth, _mask_gate, _flags)	\
+static struct ccu_mix _name =3D {							\
+	.gate	=3D CCU_GATE_INIT(_mask_gate),					\
+	.div	=3D CCU_DIV_INIT(_mshift, _mwidth),				\
+	.mux	=3D CCU_MUX_INIT(_muxshift, _muxwidth),				\
+	.common	=3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		CCU_MIX_INITHW_PARENTS(_name, _parents,				\
+				       spacemit_ccu_mux_div_gate_ops, _flags),	\
+	},									\
+}
+
+#define CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_name, _parents, _reg_ctrl, _reg_=
fc,	\
+					 _mshift, _mwidth, _mask_fc, _muxshift,	\
+					 _muxwidth, _mask_gate, _flags)		\
+static struct ccu_mix _name =3D {							\
+	.gate	=3D CCU_GATE_INIT(_mask_gate),					\
+	.div	=3D CCU_DIV_INIT(_mshift, _mwidth),				\
+	.mux	=3D CCU_MUX_INIT(_muxshift, _muxwidth),				\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		.reg_fc		=3D _reg_fc,					\
+		.mask_fc	=3D _mask_fc,					\
+		CCU_MIX_INITHW_PARENTS(_name, _parents,				\
+				       spacemit_ccu_mux_div_gate_ops, _flags),	\
+	},									\
+}
+
+#define CCU_MUX_DIV_GATE_FC_DEFINE(_name, _parents, _reg_ctrl, _mshift, _m=
width,\
+				   _mask_fc, _muxshift, _muxwidth, _mask_gate,	\
+				   _flags)					\
+CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_name, _parents, _reg_ctrl, _reg_ctrl, _m=
shift,\
+				 _mwidth, _mask_fc, _muxshift, _muxwidth,	\
+				 _mask_gate, _flags)
+
+#define CCU_MUX_DIV_FC_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth=
,	\
+			      _mask_fc, _muxshift, _muxwidth, _flags)		\
+static struct ccu_mix _name =3D {							\
+	.div	=3D CCU_DIV_INIT(_mshift, _mwidth),				\
+	.mux	=3D CCU_MUX_INIT(_muxshift, _muxwidth),				\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		.reg_fc		=3D _reg_ctrl,					\
+		.mask_fc	=3D _mask_fc,					\
+		CCU_MIX_INITHW_PARENTS(_name, _parents,				\
+				       spacemit_ccu_mux_div_ops, _flags),	\
+	},									\
+}
+
+#define CCU_MUX_FC_DEFINE(_name, _parents, _reg_ctrl, _mask_fc,	_muxshift,=
	\
+			  _muxwidth, _flags)					\
+static struct ccu_mix _name =3D {							\
+	.mux	=3D CCU_MUX_INIT(_muxshift, _muxwidth),				\
+	.common =3D {								\
+		.reg_ctrl	=3D _reg_ctrl,					\
+		.reg_fc		=3D _reg_ctrl,					\
+		.mask_fc	=3D _mask_fc,					\
+		CCU_MIX_INITHW_PARENTS(_name, _parents, spacemit_ccu_mux_ops,	\
+				       _flags)					\
+	},									\
+}
+
+static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw)
+{
+	struct ccu_common *common =3D hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_mix, common);
+}
+
+extern const struct clk_ops spacemit_ccu_gate_ops;
+extern const struct clk_ops spacemit_ccu_factor_ops;
+extern const struct clk_ops spacemit_ccu_mux_ops;
+extern const struct clk_ops spacemit_ccu_div_ops;
+extern const struct clk_ops spacemit_ccu_factor_gate_ops;
+extern const struct clk_ops spacemit_ccu_div_gate_ops;
+extern const struct clk_ops spacemit_ccu_mux_gate_ops;
+extern const struct clk_ops spacemit_ccu_mux_div_ops;
+extern const struct clk_ops spacemit_ccu_mux_div_gate_ops;
+#endif /* _CCU_DIV_H_ */
diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c
new file mode 100644
index 000000000000..971c489c261a
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_pll.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/math.h>
+#include <linux/regmap.h>
+
+#include "ccu_common.h"
+#include "ccu_pll.h"
+
+#define PLL_TIMEOUT_US		3000
+#define PLL_DELAY_US		5
+
+#define PLL_SWCR3_EN		((u32)BIT(31))
+#define PLL_SWCR3_MASK		GENMASK(30, 0)
+
+static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_=
pll *pll,
+							       unsigned long rate)
+{
+	struct ccu_pll_config *config =3D &pll->config;
+	const struct ccu_pll_rate_tbl *best_entry;
+	unsigned long best_delta =3D ULONG_MAX;
+	int i;
+
+	for (i =3D 0; i < config->tbl_num; i++) {
+		const struct ccu_pll_rate_tbl *entry =3D &config->rate_tbl[i];
+		unsigned long delta =3D abs_diff(entry->rate, rate);
+
+		if (delta < best_delta) {
+			best_delta =3D delta;
+			best_entry =3D entry;
+		}
+	}
+
+	return best_entry;
+}
+
+static const struct ccu_pll_rate_tbl *ccu_pll_lookup_matched_entry(struct =
ccu_pll *pll)
+{
+	struct ccu_pll_config *config =3D &pll->config;
+	u32 swcr1, swcr3;
+	int i;
+
+	swcr1 =3D ccu_read(&pll->common, swcr1);
+	swcr3 =3D ccu_read(&pll->common, swcr3);
+	swcr3 &=3D PLL_SWCR3_MASK;
+
+	for (i =3D 0; i < config->tbl_num; i++) {
+		const struct ccu_pll_rate_tbl *entry =3D &config->rate_tbl[i];
+
+		if (swcr1 =3D=3D entry->swcr1 && swcr3 =3D=3D entry->swcr3)
+			return entry;
+	}
+
+	return NULL;
+}
+
+static void ccu_pll_update_param(struct ccu_pll *pll, const struct ccu_pll=
_rate_tbl *entry)
+{
+	struct ccu_common *common =3D &pll->common;
+
+	regmap_write(common->regmap, common->reg_swcr1, entry->swcr1);
+	ccu_update(common, swcr3, PLL_SWCR3_MASK, entry->swcr3);
+}
+
+static int ccu_pll_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_common *common =3D hw_to_ccu_common(hw);
+
+	return ccu_read(common, swcr3) & PLL_SWCR3_EN;
+}
+
+static int ccu_pll_enable(struct clk_hw *hw)
+{
+	struct ccu_pll *pll =3D hw_to_ccu_pll(hw);
+	struct ccu_common *common =3D &pll->common;
+	unsigned int tmp;
+
+	ccu_update(common, swcr3, PLL_SWCR3_EN, PLL_SWCR3_EN);
+
+	/* check lock status */
+	return regmap_read_poll_timeout_atomic(common->lock_regmap,
+					       pll->config.reg_lock,
+					       tmp,
+					       tmp & pll->config.mask_lock,
+					       PLL_DELAY_US, PLL_TIMEOUT_US);
+}
+
+static void ccu_pll_disable(struct clk_hw *hw)
+{
+	struct ccu_common *common =3D hw_to_ccu_common(hw);
+
+	ccu_update(common, swcr3, PLL_SWCR3_EN, 0);
+}
+
+/*
+ * PLLs must be gated before changing rate, which is ensured by
+ * flag CLK_SET_RATE_GATE.
+ */
+static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct ccu_pll *pll =3D hw_to_ccu_pll(hw);
+	const struct ccu_pll_rate_tbl *entry;
+
+	entry =3D ccu_pll_lookup_best_rate(pll, rate);
+	ccu_pll_update_param(pll, entry);
+
+	return 0;
+}
+
+static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct ccu_pll *pll =3D hw_to_ccu_pll(hw);
+	const struct ccu_pll_rate_tbl *entry;
+
+	entry =3D ccu_pll_lookup_matched_entry(pll);
+
+	WARN_ON_ONCE(!entry);
+
+	return entry ? entry->rate : -EINVAL;
+}
+
+static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *prate)
+{
+	struct ccu_pll *pll =3D hw_to_ccu_pll(hw);
+
+	return ccu_pll_lookup_best_rate(pll, rate)->rate;
+}
+
+static int ccu_pll_init(struct clk_hw *hw)
+{
+	struct ccu_pll *pll =3D hw_to_ccu_pll(hw);
+
+	if (ccu_pll_lookup_matched_entry(pll))
+		return 0;
+
+	ccu_pll_disable(hw);
+	ccu_pll_update_param(pll, &pll->config.rate_tbl[0]);
+
+	return 0;
+}
+
+const struct clk_ops spacemit_ccu_pll_ops =3D {
+	.init		=3D ccu_pll_init,
+	.enable		=3D ccu_pll_enable,
+	.disable	=3D ccu_pll_disable,
+	.set_rate	=3D ccu_pll_set_rate,
+	.recalc_rate	=3D ccu_pll_recalc_rate,
+	.round_rate	=3D ccu_pll_round_rate,
+	.is_enabled	=3D ccu_pll_is_enabled,
+};
diff --git a/drivers/clk/spacemit/ccu_pll.h b/drivers/clk/spacemit/ccu_pll.h
new file mode 100644
index 000000000000..bf167e22efc6
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_pll.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org>
+ */
+
+#ifndef _CCU_PLL_H_
+#define _CCU_PLL_H_
+
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+/**
+ * struct ccu_pll_rate_tbl - Structure mapping between PLL rate and regist=
er
+ * configuration.
+ *
+ * @rate:	PLL rate
+ * @swcr1:	Register value of PLLX_SW1_CTRL (PLLx_SWCR1).
+ * @swcr3:	Register value of the PLLx_SW3_CTRL's lowest 31 bits of
+ *		PLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling
+ *		the PLL and not contained in this field.
+ */
+struct ccu_pll_rate_tbl {
+	unsigned long rate;
+	u32 swcr1;
+	u32 swcr3;
+};
+
+struct ccu_pll_config {
+	const struct ccu_pll_rate_tbl *rate_tbl;
+	u32 tbl_num;
+	u32 reg_lock;
+	u32 mask_lock;
+};
+
+#define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \
+	{									\
+		.rate	=3D _rate,							\
+		.swcr1	=3D _swcr1,						\
+		.swcr3	=3D _swcr3,						\
+	}
+
+struct ccu_pll {
+	struct ccu_common	common;
+	struct ccu_pll_config	config;
+};
+
+#define CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock) \
+	{									\
+		.rate_tbl	=3D _table,					\
+		.tbl_num	=3D ARRAY_SIZE(_table),				\
+		.reg_lock	=3D (_reg_lock),					\
+		.mask_lock	=3D (_mask_lock),					\
+	}
+
+#define CCU_PLL_HWINIT(_name, _flags)						\
+	(&(struct clk_init_data) {						\
+		.name		=3D #_name,					\
+		.ops		=3D &spacemit_ccu_pll_ops,			\
+		.parent_data	=3D &(struct clk_parent_data) { .index =3D 0 },	\
+		.num_parents	=3D 1,						\
+		.flags		=3D _flags,					\
+	})
+
+#define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, _reg_lock,	\
+		       _mask_lock, _flags)					\
+static struct ccu_pll _name =3D {							\
+	.config	=3D CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock),		\
+	.common =3D {								\
+		.reg_swcr1	=3D _reg_swcr1,					\
+		.reg_swcr3	=3D _reg_swcr3,					\
+		.hw.init	=3D CCU_PLL_HWINIT(_name, _flags)			\
+	}									\
+}
+
+static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw)
+{
+	struct ccu_common *common =3D hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_pll, common);
+}
+
+extern const struct clk_ops spacemit_ccu_pll_ops;
+
+#endif
--=20
2.49.0
From nobody Tue May 13 04:18:04 2025
Received: from bayard.4d2.org (bayard.4d2.org [155.254.16.17])
	(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 BE72320F076;
	Tue,  1 Apr 2025 17:25:09 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=155.254.16.17
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743528311; cv=none;
 b=UC+8bhLV69UEMc82JFw5/nxhwze9CJ1POws23wPmLffU2+W73aFqaYNQPt/CQsBzFVYAX055nXhftHZjVdztD3EWux+GBeiZiDfxSpKUfrSl4SFw7pegNQy3MB8CH8undHznvwF4cReyszGwJxBT0UjlgFXgYk4BQ3o3lieKPfE=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743528311; c=relaxed/simple;
	bh=UEi+X0opYSOBwIaTJ9L7fBGwSzYPjuB8SAkUHzqDMpY=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=POiOpbWfKtt7YiyZfXoQDWf/+knbiGofWNyqp23IQLg+lRdvYny1LpZV+ozawmIDBjYv2gcCc3tFzOIrsRR3SGPL5VCHQF3F37KIfePUGKWmUlxgE7ezwzEdLR1Vvv8skTkywXsuEx2dN8U0GsRelsNWOfr8oCmQU0wtiN2G898=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org;
 spf=pass smtp.mailfrom=4d2.org;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=DUeTCDdf;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=I5V0Kwfu; arc=none smtp.client-ip=155.254.16.17
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="DUeTCDdf";
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="I5V0Kwfu"
Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1])
	by bayard.4d2.org (Postfix) with ESMTP id 3D4FBEC59FF;
	Tue, 01 Apr 2025 10:25:09 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528309; bh=UEi+X0opYSOBwIaTJ9L7fBGwSzYPjuB8SAkUHzqDMpY=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=DUeTCDdfAVv1Y7xtcJVYWxH34aLy509JtCmh6yrDvBHT+mpfzaBeEIffW4X2X1tZg
	 maTJlPm+Yxh7tl1ZGpmPeB3DoUvt1mqWwlxpbAgchxJ2RxxaWY17AxKpWmk6aeDv7k
	 xOi+0dRb/SgQI/EoxP2PB1Zhs2sTBhViDdnwzYi37bLRpZXRU4vUHglUBOlaLkpA9Q
	 9dwFaQ4xfAJ357GWbF2G4GbJ6E+Pml1scpsqKzKBf4vW1CipityUpBAh6gPeSm8vbt
	 VlL8Enokfj2f7dlvcBO2DV1vI2czp0bSSAVLIdv3LDdsMaRiZPhMMhJvn1o7YwD2N8
	 /4i3xNI8Y2a8A==
X-Virus-Scanned: amavisd-new at 4d2.org
Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key)
 header.d=4d2.org
Received: from bayard.4d2.org ([127.0.0.1])
 by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id I-7M24s2H3k1; Tue,  1 Apr 2025 10:25:08 -0700 (PDT)
Received: from localhost.localdomain (unknown [183.217.81.55])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange x25519 server-signature ECDSA (prime256v1) server-digest
 SHA256)
	(No client certificate requested)
	(Authenticated sender: heylenay@4d2.org)
	by bayard.4d2.org (Postfix) with ESMTPSA id 405D7EC59F9;
	Tue, 01 Apr 2025 10:25:03 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528307; bh=UEi+X0opYSOBwIaTJ9L7fBGwSzYPjuB8SAkUHzqDMpY=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=I5V0Kwfu19eg10Kz2m6Tghi4JitDOo3WUhjJ76ob2uAqQcY3KUQgURnUrzSo5HaKC
	 ultpXw+gQZYvVDKEQ6yKHJUBb3Vby3JE+WikS1NgA847n9BNrLcFQaSwcJoO8CfyFQ
	 9j2XrOx/Eq564WeSIocrqJuazxlqCBlUm0wdRJaH+SURyaK2WIfIyU/JrLiABbTYl6
	 +x27Q8IjeQG0y1Hwl9ZslB1uz06TzY+EjCUZMiE/c54o4oz+OpJsqCfNsBuS7S9gSQ
	 g221j1EblU7E6RgnzEnh4grINQrUk65xYDfiDRA40i+b1ils155ocIaHRrMgx+Qc5e
	 bCWO7iHjUtw/g==
From: Haylen Chu <heylenay@4d2.org>
To: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Haylen Chu <heylenay@outlook.com>,
	Yixun Lan <dlan@gentoo.org>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>
Cc: linux-riscv@lists.infradead.org,
	linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	spacemit@lists.linux.dev,
	Inochi Amaoto <inochiama@outlook.com>,
	Chen Wang <unicornxdotw@foxmail.com>,
	Jisheng Zhang <jszhang@kernel.org>,
	Meng Zhang <zhangmeng.kevin@linux.spacemit.com>,
	Haylen Chu <heylenay@4d2.org>
Subject: [PATCH v6 4/6] clk: spacemit: k1: Add TWSI8 bus and function clocks
Date: Tue,  1 Apr 2025 17:24:32 +0000
Message-ID: <20250401172434.6774-5-heylenay@4d2.org>
X-Mailer: git-send-email 2.49.0
In-Reply-To: <20250401172434.6774-1-heylenay@4d2.org>
References: <20250401172434.6774-1-heylenay@4d2.org>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

The control register for TWSI8 clocks, APBC_TWSI8_CLK_RST, contains mux
selection bits, reset assertion bit and enable bits for function and bus
clocks. It has a quirk that reading always results in zero.

As a workaround, let's hardcode the mux value as zero to select
pll1_d78_31p5 as parent and treat twsi8_clk as a gate, whose enable mask
is combined from the real bus and function clocks to avoid the
write-only register being shared between two clk_hws, in which case
updates of one clk_hw zero the other's bits.

With a 1:1 factor serving as placeholder for the bus clock, the I2C-8
controller could be brought up, which is essential for boards attaching
power-management chips to it.

Signed-off-by: Haylen Chu <heylenay@4d2.org>
Reviewed-by: Alex Elder <elder@riscstar.com>
---
 drivers/clk/spacemit/ccu-k1.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c
index cd95c4f9c127..5804c2f85407 100644
--- a/drivers/clk/spacemit/ccu-k1.c
+++ b/drivers/clk/spacemit/ccu-k1.c
@@ -397,6 +397,8 @@ CCU_MUX_GATE_DEFINE(twsi6_clk, twsi_parents, APBC_TWSI6=
_CLK_RST, 4, 3, BIT(1),
 		    0);
 CCU_MUX_GATE_DEFINE(twsi7_clk, twsi_parents, APBC_TWSI7_CLK_RST, 4, 3, BIT=
(1),
 		    0);
+CCU_GATE_DEFINE(twsi8_clk, CCU_PARENT_HW(pll1_d78_31p5), APBC_TWSI8_CLK_RS=
T,
+		BIT(1) | BIT(0), 0);
=20
 static const struct clk_parent_data timer_parents[] =3D {
 	CCU_PARENT_HW(pll1_d192_12p8),
@@ -528,6 +530,7 @@ CCU_GATE_DEFINE(twsi6_bus_clk, CCU_PARENT_HW(apb_clk), =
APBC_TWSI6_CLK_RST,
 		BIT(0), 0);
 CCU_GATE_DEFINE(twsi7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI7_CLK_RST,
 		BIT(0), 0);
+CCU_FACTOR_DEFINE(twsi8_bus_clk, CCU_PARENT_HW(apb_clk), 1, 1);
=20
 CCU_GATE_DEFINE(timers1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS1_CLK_=
RST,
 		BIT(0), 0);
@@ -1059,6 +1062,7 @@ static struct clk_hw *k1_ccu_apbc_hws[] =3D {
 	[CLK_TWSI5]		=3D &twsi5_clk.common.hw,
 	[CLK_TWSI6]		=3D &twsi6_clk.common.hw,
 	[CLK_TWSI7]		=3D &twsi7_clk.common.hw,
+	[CLK_TWSI8]		=3D &twsi8_clk.common.hw,
 	[CLK_TIMERS1]		=3D &timers1_clk.common.hw,
 	[CLK_TIMERS2]		=3D &timers2_clk.common.hw,
 	[CLK_AIB]		=3D &aib_clk.common.hw,
@@ -1110,6 +1114,7 @@ static struct clk_hw *k1_ccu_apbc_hws[] =3D {
 	[CLK_TWSI5_BUS]		=3D &twsi5_bus_clk.common.hw,
 	[CLK_TWSI6_BUS]		=3D &twsi6_bus_clk.common.hw,
 	[CLK_TWSI7_BUS]		=3D &twsi7_bus_clk.common.hw,
+	[CLK_TWSI8_BUS]		=3D &twsi8_bus_clk.common.hw,
 	[CLK_TIMERS1_BUS]	=3D &timers1_bus_clk.common.hw,
 	[CLK_TIMERS2_BUS]	=3D &timers2_bus_clk.common.hw,
 	[CLK_AIB_BUS]		=3D &aib_bus_clk.common.hw,
--=20
2.49.0
From nobody Tue May 13 04:18:04 2025
Received: from bayard.4d2.org (bayard.4d2.org [155.254.16.17])
	(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 E761A20FA96;
	Tue,  1 Apr 2025 17:25:14 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=155.254.16.17
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743528316; cv=none;
 b=cR8ZE26U1PHeQ0HqatnPzSwnRl4/EZUwU1ah2UyesVtdAp9F6t/0YrJDmVMd0izxTUBDunZpvwXoagjwmo/CFbOFWbTfvw6A+UYIazY5gGMsbInwRfLXyYLBtpXAd0MM+a9F2Fn/8P4+BHcovXUG3X8wR+seedrx+IGSWxC7KHk=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743528316; c=relaxed/simple;
	bh=s5+2LV5qzGfSoaUmOTmwclmoPaprfIhEiBb+RxjFEmM=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=EhaAjYyb+R1MhFGZCVwbNScNCmgLVcVqkANPMBAJVlfZM1lVKY4Wr1DpdfGNzG37tHDTdIamkeXUUBuSu4U468+XKVpMReDF/+15nZwk58F+cYic5/9P0TGkmHdiJ8b1K8oXfkyPDVeqhQElk3RM8u+4txa4yM4jAyezGf8Asn0=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org;
 spf=pass smtp.mailfrom=4d2.org;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=YDhwXk1k;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=g5/9Cbax; arc=none smtp.client-ip=155.254.16.17
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="YDhwXk1k";
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="g5/9Cbax"
Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1])
	by bayard.4d2.org (Postfix) with ESMTP id 5F373EC59FE;
	Tue, 01 Apr 2025 10:25:14 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528314; bh=s5+2LV5qzGfSoaUmOTmwclmoPaprfIhEiBb+RxjFEmM=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=YDhwXk1kPly4aQsdTaxucqzwaYqRaKqYWr42M1/GtGO08X/D+4SV7iTxPReMUzeRS
	 rZCVxkZjqXhY8pRzxWRfi86hUkNuwwJq9MZ70Y0GMqrT6Cmu52Ko8xqRGnfgfrrqOk
	 Dyh8BdhTPgr89s2dTlG7DzOmqvnSgXAHAgjpGtlH0uTnxjT+axDJjwX26IqrpNQ27X
	 bYlyhsET4DBAbBT13+7qfhi/VDNvslLFGdYG9sNgfHkPo4umxvGHoBgNvHDB11z/WG
	 RS1Jkz8wTA4bajupV//9oyr4uBfGijkyCqNUv07d9ZodKj+5ifGYkREOAZ++m+tPse
	 lbsptewU56now==
X-Virus-Scanned: amavisd-new at 4d2.org
Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key)
 header.d=4d2.org
Received: from bayard.4d2.org ([127.0.0.1])
 by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id R0Me9iEaze46; Tue,  1 Apr 2025 10:25:13 -0700 (PDT)
Received: from localhost.localdomain (unknown [183.217.81.55])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange x25519 server-signature ECDSA (prime256v1) server-digest
 SHA256)
	(No client certificate requested)
	(Authenticated sender: heylenay@4d2.org)
	by bayard.4d2.org (Postfix) with ESMTPSA id 6CAA2EC59FC;
	Tue, 01 Apr 2025 10:25:08 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528313; bh=s5+2LV5qzGfSoaUmOTmwclmoPaprfIhEiBb+RxjFEmM=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=g5/9CbaxPA6XwL2l01itGIS6+X51kE8Ajg2+Zi1Hedq8IRKepquRDAGxVdSgL2OGl
	 r0lh2/8mqhWeNmb6r8WjtkEyv1RcG6HAqJsydIWAJXhXISoDop3kIscux+pg7PT43d
	 1/W7grTWu7S2UiW5mS0lJ/1Eg6BcPOd6HDTLjauy4vd/WoZYrLx0nEUceJ9UEi0JUd
	 kX6TAktlukHmLfPICTCRF2NVjbobJXl2ej/5eWoQqrrj1wCFaJ9St78slIE9sPcPL6
	 ZcGV8aYUdSqY1zXdYN0unNNkQpGDpNGQVAWSdDOZqPkTXPt7+TDG4vqUPUtVThl/vK
	 k2xpbpT3mnlAg==
From: Haylen Chu <heylenay@4d2.org>
To: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Haylen Chu <heylenay@outlook.com>,
	Yixun Lan <dlan@gentoo.org>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>
Cc: linux-riscv@lists.infradead.org,
	linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	spacemit@lists.linux.dev,
	Inochi Amaoto <inochiama@outlook.com>,
	Chen Wang <unicornxdotw@foxmail.com>,
	Jisheng Zhang <jszhang@kernel.org>,
	Meng Zhang <zhangmeng.kevin@linux.spacemit.com>,
	Haylen Chu <heylenay@4d2.org>
Subject: [PATCH v6 5/6] riscv: dts: spacemit: Add clock tree for SpacemiT K1
Date: Tue,  1 Apr 2025 17:24:33 +0000
Message-ID: <20250401172434.6774-6-heylenay@4d2.org>
X-Mailer: git-send-email 2.49.0
In-Reply-To: <20250401172434.6774-1-heylenay@4d2.org>
References: <20250401172434.6774-1-heylenay@4d2.org>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

Describe the PLL and system controllers that're capable of generating
clock signals in the devicetree.

Signed-off-by: Haylen Chu <heylenay@4d2.org>
Reviewed-by: Alex Elder <elder@riscstar.com>
---
 arch/riscv/boot/dts/spacemit/k1.dtsi | 75 ++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spa=
cemit/k1.dtsi
index c670ebf8fa12..584f0dbc60f5 100644
--- a/arch/riscv/boot/dts/spacemit/k1.dtsi
+++ b/arch/riscv/boot/dts/spacemit/k1.dtsi
@@ -3,6 +3,8 @@
  * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name>
  */
=20
+#include <dt-bindings/clock/spacemit,k1-syscon.h>
+
 /dts-v1/;
 / {
 	#address-cells =3D <2>;
@@ -306,6 +308,36 @@ cluster1_l2_cache: l2-cache1 {
 		};
 	};
=20
+	clocks {
+		vctcxo_1m: clock-1m {
+			compatible =3D "fixed-clock";
+			clock-frequency =3D <1000000>;
+			clock-output-names =3D "vctcxo_1m";
+			#clock-cells =3D <0>;
+		};
+
+		vctcxo_24m: clock-24m {
+			compatible =3D "fixed-clock";
+			clock-frequency =3D <24000000>;
+			clock-output-names =3D "vctcxo_24m";
+			#clock-cells =3D <0>;
+		};
+
+		vctcxo_3m: clock-3m {
+			compatible =3D "fixed-clock";
+			clock-frequency =3D <3000000>;
+			clock-output-names =3D "vctcxo_3m";
+			#clock-cells =3D <0>;
+		};
+
+		osc_32k: clock-32k {
+			compatible =3D "fixed-clock";
+			clock-frequency =3D <32000>;
+			clock-output-names =3D "osc_32k";
+			#clock-cells =3D <0>;
+		};
+	};
+
 	soc {
 		compatible =3D "simple-bus";
 		interrupt-parent =3D <&plic>;
@@ -314,6 +346,17 @@ soc {
 		dma-noncoherent;
 		ranges;
=20
+		syscon_apbc: system-control@d4015000 {
+			compatible =3D "spacemit,k1-syscon-apbc";
+			reg =3D <0x0 0xd4015000 0x0 0x1000>;
+			clocks =3D <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>,
+				 <&vctcxo_24m>;
+			clock-names =3D "osc", "vctcxo_1m", "vctcxo_3m",
+				      "vctcxo_24m";
+			#clock-cells =3D <1>;
+			#reset-cells =3D <1>;
+		};
+
 		uart0: serial@d4017000 {
 			compatible =3D "spacemit,k1-uart", "intel,xscale-uart";
 			reg =3D <0x0 0xd4017000 0x0 0x100>;
@@ -409,6 +452,38 @@ pinctrl: pinctrl@d401e000 {
 			reg =3D <0x0 0xd401e000 0x0 0x400>;
 		};
=20
+		syscon_mpmu: system-controller@d4050000 {
+			compatible =3D "spacemit,k1-syscon-mpmu";
+			reg =3D <0x0 0xd4050000 0x0 0x209c>;
+			clocks =3D <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>,
+				 <&vctcxo_24m>;
+			clock-names =3D "osc", "vctcxo_1m", "vctcxo_3m",
+				      "vctcxo_24m";
+			#clock-cells =3D <1>;
+			#power-domain-cells =3D <1>;
+			#reset-cells =3D <1>;
+		};
+
+		pll: system-control@d4090000 {
+			compatible =3D "spacemit,k1-pll";
+			reg =3D <0x0 0xd4090000 0x0 0x1000>;
+			clocks =3D <&vctcxo_24m>;
+			spacemit,mpmu =3D <&syscon_mpmu>;
+			#clock-cells =3D <1>;
+		};
+
+		syscon_apmu: system-control@d4282800 {
+			compatible =3D "spacemit,k1-syscon-apmu";
+			reg =3D <0x0 0xd4282800 0x0 0x400>;
+			clocks =3D <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>,
+				 <&vctcxo_24m>;
+			clock-names =3D "osc", "vctcxo_1m", "vctcxo_3m",
+				      "vctcxo_24m";
+			#clock-cells =3D <1>;
+			#power-domain-cells =3D <1>;
+			#reset-cells =3D <1>;
+		};
+
 		plic: interrupt-controller@e0000000 {
 			compatible =3D "spacemit,k1-plic", "sifive,plic-1.0.0";
 			reg =3D <0x0 0xe0000000 0x0 0x4000000>;
--=20
2.49.0
From nobody Tue May 13 04:18:04 2025
Received: from bayard.4d2.org (bayard.4d2.org [155.254.16.17])
	(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 3067920FA96;
	Tue,  1 Apr 2025 17:25:19 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
 arc=none smtp.client-ip=155.254.16.17
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
	t=1743528321; cv=none;
 b=PNnuXEZkQ7KjhoQ4TkpKBp63B1BaUxpav70hjbB2BPnZBbNDvBq7mx0XOOHRjUvv0OEKQECPm5sc/rFIIURCtF0jy+qdKNXmIyek3ql+MJI4hUdpQhcTIrKpH0X2CxckYoZluvIZmRNv9Jh1Uq/b+dgl7nQOwRgtURLIJEsrJ2w=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
	s=arc-20240116; t=1743528321; c=relaxed/simple;
	bh=34/DWVz3xny62FFtko1B9kiCB28YM6UFyyWMYVeeQig=;
	h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:
	 MIME-Version;
 b=me3huKQtMaGrgIfC06jUwuLLfLHdGC+fBnGceksQEeh2EetoTJ5jcqH403eCDT1v8Pis81BD3BDhfQU3yKoPRA52vZnpFcdoS/v3sRzRUG+f4+mDPdjYnt0dBi4p5ms2UqfEQuceX7YlZz7PDKRWmtUflkaiRvzoST1GlWemQoQ=
ARC-Authentication-Results: i=1; smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org;
 spf=pass smtp.mailfrom=4d2.org;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=0n3w3k1x;
 dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b=yKw1lY92; arc=none smtp.client-ip=155.254.16.17
Authentication-Results: smtp.subspace.kernel.org;
 dmarc=pass (p=reject dis=none) header.from=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
 spf=pass smtp.mailfrom=4d2.org
Authentication-Results: smtp.subspace.kernel.org;
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="0n3w3k1x";
	dkim=pass (2048-bit key) header.d=4d2.org header.i=@4d2.org
 header.b="yKw1lY92"
Received: from bayard.4d2.org (bayard.4d2.org [127.0.0.1])
	by bayard.4d2.org (Postfix) with ESMTP id 8FC6EEC59FC;
	Tue, 01 Apr 2025 10:25:19 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528319; bh=34/DWVz3xny62FFtko1B9kiCB28YM6UFyyWMYVeeQig=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=0n3w3k1xYwdVRZSlz/Co5xIF215jsdpvvl4PjqqpwaAmb4R1oNi2GtuosqR7h0I15
	 vLOqdD8yasEubHEYZvBVjAK4Re6igpKPSfc2VVw8ie3uLSY3SJYeFdvqwvesWMUilH
	 Vh5THxvLLBhABaqWImTOqLc77Nw17t0D4wxGiqeBmJz+2wLZuezHr0M3ZTP6/Guo29
	 wRrmreuaMlHaHWalBUJqgkVwxLNHPs8zQjDwca7Eliqb1yLDnjYCPlyBrpR23MvY0I
	 FWJRGl22II2zVxYRGetW1P0l7Qn4tiAmJ91JnDOY7RPv6ghKUonq0A+WwfJra9u9xK
	 7ijDNhYFEODjg==
X-Virus-Scanned: amavisd-new at 4d2.org
Authentication-Results: bayard.4d2.org (amavisd-new); dkim=pass (2048-bit key)
 header.d=4d2.org
Received: from bayard.4d2.org ([127.0.0.1])
 by bayard.4d2.org (bayard.4d2.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id 78L11jvBmuvM; Tue,  1 Apr 2025 10:25:18 -0700 (PDT)
Received: from localhost.localdomain (unknown [183.217.81.55])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange x25519 server-signature ECDSA (prime256v1) server-digest
 SHA256)
	(No client certificate requested)
	(Authenticated sender: heylenay@4d2.org)
	by bayard.4d2.org (Postfix) with ESMTPSA id 95CDDEC59F9;
	Tue, 01 Apr 2025 10:25:13 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=4d2.org; s=mail;
	t=1743528318; bh=34/DWVz3xny62FFtko1B9kiCB28YM6UFyyWMYVeeQig=;
	h=From:To:Cc:Subject:Date:In-Reply-To:References:From;
	b=yKw1lY92V5SLbhmR0TXij6E8ysSSTLOQMUTEn6BbEYML/l+e1vIWu8EaogEntPrAI
	 fzW4XFz2Egr4WfkLcp5ZdXiNCiSupFburyQmdmS/jB0xAgL60sIBF+qzea857cVJuC
	 J010vRFd0AUJkaYKGptzjD9b123zjWJ16FAyJG4M2F7e8ghSH5nsUmTCdDRmSARsr2
	 xR9qREPzi01bX4enCr4nzxr4Nmc777hKTGpLoLqDGb7EgMVrkx0LA8qnegnXPITD35
	 M+hpc1zMeI/Df/yT9sLphTcngxRHA0dXs/PwbnifbJIuvsUOGCKbvYd12ms1BUcMdx
	 rEi2WmFSqVlMA==
From: Haylen Chu <heylenay@4d2.org>
To: Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Haylen Chu <heylenay@outlook.com>,
	Yixun Lan <dlan@gentoo.org>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>
Cc: linux-riscv@lists.infradead.org,
	linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	spacemit@lists.linux.dev,
	Inochi Amaoto <inochiama@outlook.com>,
	Chen Wang <unicornxdotw@foxmail.com>,
	Jisheng Zhang <jszhang@kernel.org>,
	Meng Zhang <zhangmeng.kevin@linux.spacemit.com>,
	Haylen Chu <heylenay@4d2.org>
Subject: [PATCH v6 6/6] riscv: defconfig: enable clock controller unit support
 for SpacemiT K1
Date: Tue,  1 Apr 2025 17:24:34 +0000
Message-ID: <20250401172434.6774-7-heylenay@4d2.org>
X-Mailer: git-send-email 2.49.0
In-Reply-To: <20250401172434.6774-1-heylenay@4d2.org>
References: <20250401172434.6774-1-heylenay@4d2.org>
Precedence: bulk
X-Mailing-List: linux-kernel@vger.kernel.org
List-Id: <linux-kernel.vger.kernel.org>
List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org>
List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org>
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"

Clock controller unit, or CCU, generates various clocks frequency for
peripherals integrated in SpacemiT K1 SoC and is essential for normal
operation. Let's enable it in defconfig.

Signed-off-by: Haylen Chu <heylenay@4d2.org>
---
 arch/riscv/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index 0f7dcbe3c45b..011788d16d93 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -252,6 +252,8 @@ CONFIG_CLK_SOPHGO_CV1800=3Dy
 CONFIG_CLK_SOPHGO_SG2042_PLL=3Dy
 CONFIG_CLK_SOPHGO_SG2042_CLKGEN=3Dy
 CONFIG_CLK_SOPHGO_SG2042_RPGATE=3Dy
+CONFIG_SPACEMIT_CCU=3Dy
+CONFIG_SPACEMIT_K1_CCU=3Dy
 CONFIG_SUN8I_DE2_CCU=3Dm
 CONFIG_SUN50I_IOMMU=3Dy
 CONFIG_RPMSG_CHAR=3Dy
--=20
2.49.0