mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] Add clock controller support for Spacemit K1
@ 2024-08-31 15:45 Haylen Chu
  2024-08-31 15:47 ` [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC Haylen Chu
  2024-08-31 15:47 ` [PATCH 2/2] clk: spacemit: Add clock support for " Haylen Chu
  0 siblings, 2 replies; 9+ messages in thread
From: Haylen Chu @ 2024-08-31 15:45 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-clk, devicetree, linux-kernel, Haylen Chu

The clock tree of Spacemit K1 is managed by several independent
controllers in different SoC parts. In this series, only all clock
hardwares in APBS and MPMU, and some in APBC and APMU, are implemented,
which is enough to bring up CPU cores and UARTs with some changes to
UART driver (see below). More clocks will be implemented later soon.

No device tree changes are included since Spacemit K1 UART needs two
clocks to operate, but for now the driver gets only one. I would like to
defer the changes until this is resolved.

Tested on BananaPi-F3 board, a clock tree dump could be obtained here[1].

[1]: https://gist.github.com/heylenayy/aaeac90e4fc95a7078825642b7240f47

Link: https://developer.spacemit.com/documentation?token=LCrKwWDasiJuROkVNusc2pWTnEb

Haylen Chu (2):
  dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC
  clk: spacemit: Add clock support for Spacemit K1 SoC

 .../bindings/clock/spacemit,ccu.yaml          | 116 ++++
 drivers/clk/Kconfig                           |   1 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/spacemit/Kconfig                  |  10 +
 drivers/clk/spacemit/Makefile                 |   4 +
 drivers/clk/spacemit/ccu-spacemit.c           | 594 ++++++++++++++++++
 drivers/clk/spacemit/ccu_common.h             |  55 ++
 drivers/clk/spacemit/ccu_ddn.c                | 167 +++++
 drivers/clk/spacemit/ccu_ddn.h                |  84 +++
 drivers/clk/spacemit/ccu_mix.c                | 338 ++++++++++
 drivers/clk/spacemit/ccu_mix.h                | 349 ++++++++++
 drivers/clk/spacemit/ccu_pll.c                | 229 +++++++
 drivers/clk/spacemit/ccu_pll.h                |  82 +++
 include/dt-bindings/clock/spacemit,ccu.h      | 197 ++++++
 14 files changed, 2227 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
 create mode 100644 drivers/clk/spacemit/Kconfig
 create mode 100644 drivers/clk/spacemit/Makefile
 create mode 100644 drivers/clk/spacemit/ccu-spacemit.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
 create mode 100644 include/dt-bindings/clock/spacemit,ccu.h


base-commit: 3d5f968a177d468cd13568ef901c5be84d83d32b
prerequisite-patch-id: 47dcf6861f7d434d25855b379e6d7ef4ce369c9c
prerequisite-patch-id: 77787fe82911923aff15ccf565e8fa451538c3a6
prerequisite-patch-id: b0bdb1742d96c5738f05262c3b0059102761390b
prerequisite-patch-id: 3927d39d8d77e35d5bfe53d9950da574ff8f2054
prerequisite-patch-id: a98039136a4796252a6029e474f03906f2541643
prerequisite-patch-id: c95f6dc0547a2a63a76e3cba0cf5c623b212b4e6
prerequisite-patch-id: 66e750e438ee959ddc2a6f0650814a2d8c989139
prerequisite-patch-id: 29a0fd8c36c1a4340f0d0b68a4c34d2b8abfb1ab
prerequisite-patch-id: 0bdfff661c33c380d1cf00a6c68688e05f88c0b3
prerequisite-patch-id: 99f15718e0bfbb7ed1a96dfa19f35841b004dae9
-- 
2.46.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC
  2024-08-31 15:45 [PATCH 0/2] Add clock controller support for Spacemit K1 Haylen Chu
@ 2024-08-31 15:47 ` Haylen Chu
  2024-08-31 17:19   ` Rob Herring (Arm)
                     ` (3 more replies)
  2024-08-31 15:47 ` [PATCH 2/2] clk: spacemit: Add clock support for " Haylen Chu
  1 sibling, 4 replies; 9+ messages in thread
From: Haylen Chu @ 2024-08-31 15:47 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-clk, devicetree, linux-kernel, Haylen Chu

Add definition for the clock controllers of Spacemit K1 SoC. The clock
tree is managed by several SoC parts, thus different compatible strings
are added for each.

Signed-off-by: Haylen Chu <heylenay@outlook.com>
---
 .../bindings/clock/spacemit,ccu.yaml          | 116 +++++++++++
 include/dt-bindings/clock/spacemit,ccu.h      | 197 ++++++++++++++++++
 2 files changed, 313 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
 create mode 100644 include/dt-bindings/clock/spacemit,ccu.h

diff --git a/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
new file mode 100644
index 000000000000..90ddfc5e2a2f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/spacemit,ccu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Spacemit SoC Clock Controller
+
+maintainers:
+  - Haylen Chu <heylenay@outlook.com>
+
+properties:
+  compatible:
+    enum:
+      - spacemit,ccu-apbs
+      - spacemit,ccu-mpmu
+      - spacemit,ccu-apbc
+      - spacemit,ccu-apmu
+
+  clocks: true
+
+  clock-names: true
+
+  spacemit,mpmu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon managing "Main PMU (MPMU)" registers
+
+  "#clock-cells":
+    const: 1
+    description:
+      See <dt-bindings/clock/spacemit,ccu.h> for valid indices.
+
+required:
+  - compatible
+  - "#clock-cells"
+
+additionalProperties: false
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: spacemit,ccu-apbs
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+
+        clock-names:
+          const: pll1_2457p6_vco
+
+      required:
+        - compatible
+        - clocks
+        - clock-names
+        - "#clock-cells"
+        - spacemit,mpmu
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: spacemit,ccu-apbc
+    then:
+      properties:
+        clocks:
+          maxItems: 4
+
+        clock-names:
+          items:
+            - const: clk_32k
+            - const: vctcxo_1
+            - const: vctcxo_24
+            - const: vctcxo_3
+
+      required:
+        - compatible
+        - clocks
+        - clock-names
+        - "#clock-cells"
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: spacemit,ccu-apmu
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+
+        clock-names:
+          const: vctcxo_24
+
+      required:
+        - compatible
+        - clocks
+        - clock-names
+        - "#clock-cells"
+
+examples:
+  - |
+    syscon_apbs: system-control@d4090000 {
+        compatible = "spacemit,mpmu-syscon", "syscon",
+        "simple-mfd";
+        reg = <0x0 0xd4090000 0x0 0x1000>;
+
+        clk_apbs: clock-controller {
+            compatible = "spacemit,ccu-apbs";
+            clocks = <&pll1_2457p6_vco>;
+            clock-names = "pll1_2457p6_vco";
+            #clock-cells = <1>;
+            spacemit,mpmu = <&syscon_mpmu>;
+        };
+    };
diff --git a/include/dt-bindings/clock/spacemit,ccu.h b/include/dt-bindings/clock/spacemit,ccu.h
new file mode 100644
index 000000000000..ce84690684ff
--- /dev/null
+++ b/include/dt-bindings/clock/spacemit,ccu.h
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (C) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+
+#ifndef _DT_BINDINGS_SPACEMIT_CCU_H_
+#define _DT_BINDINGS_SPACEMIT_CCU_H_
+
+/*	APBS clocks	*/
+#define CLK_PLL2		0
+#define CLK_PLL3		1
+#define CLK_PLL1_D2		2
+#define CLK_PLL1_D3		3
+#define CLK_PLL1_D4		4
+#define CLK_PLL1_D5		5
+#define CLK_PLL1_D6		6
+#define CLK_PLL1_D7		7
+#define CLK_PLL1_D8		8
+#define CLK_PLL1_D11		9
+#define CLK_PLL1_D13		10
+#define CLK_PLL1_D23		11
+#define CLK_PLL1_D64		12
+#define CLK_PLL1_D10_AUD	13
+#define CLK_PLL1_D100_AUD	14
+#define CLK_PLL2_D1		15
+#define CLK_PLL2_D2		16
+#define CLK_PLL2_D3		17
+#define CLK_PLL2_D4		18
+#define CLK_PLL2_D5		19
+#define CLK_PLL2_D6		20
+#define CLK_PLL2_D7		21
+#define CLK_PLL2_D8		22
+#define CLK_PLL3_D1		23
+#define CLK_PLL3_D2		24
+#define CLK_PLL3_D3		25
+#define CLK_PLL3_D4		26
+#define CLK_PLL3_D5		27
+#define CLK_PLL3_D6		28
+#define CLK_PLL3_D7		29
+#define CLK_PLL3_D8		30
+#define CLK_PLL3_80		31
+#define CLK_PLL3_40		32
+#define CLK_PLL3_20		33
+#define CLK_APBS_NUM		34
+
+/*	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_351		15
+#define CLK_PLL1_409P6		16
+#define CLK_PLL1_204P8		17
+#define CLK_PLL1_491		18
+#define CLK_PLL1_245P76		19
+#define CLK_PLL1_614		20
+#define CLK_PLL1_47P26		21
+#define CLK_PLL1_31P5		22
+#define CLK_PLL1_819		23
+#define CLK_PLL1_1228		24
+#define CLK_SLOW_UART		25
+#define CLK_SLOW_UART1		26
+#define CLK_SLOW_UART2		27
+#define CLK_WDT			28
+#define CLK_RIPC		29
+#define CLK_I2S_SySCLK		30
+#define CLK_I2S_BCLK		31
+#define CLK_APB			32
+#define CLK_MPMU_NUM		33
+
+/*	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_APBC_NUM		52
+
+/*	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		28
+#define CLK_PCIE1		29
+#define CLK_PCIE2		30
+#define CLK_EMAC0_BUS		31
+#define CLK_EMAC0_PTP		32
+#define CLK_EMAC1_BUS		33
+#define CLK_EMAC1_PTP		34
+#define CLK_JPG			35
+#define CLK_JPF_4KAFBC		36
+#define CLK_JPF_2KAFBC		37
+#define CLK_CCIC2PHY		38
+#define CLK_CCIC3PHY		39
+#define CLK_CSI			40
+#define CLK_CAMM0		41
+#define CLK_CAMM1		42
+#define CLK_CAMM2		43
+#define CLK_ISP_CPP		44
+#define CLK_ISP_BUS		45
+#define CLK_ISP			46
+#define CLK_DPU_MCL		47
+#define CLK_DPU_ESC		48
+#define CLK_DPU_BIT		49
+#define CLK_DPU_PXCLK		50
+#define CLK_DPU_HCLK		51
+#define CLK_DPU_SPI		52
+#define CLK_DPU_SPI_HBUS	53
+#define CLK_DPU_SPIBUS		54
+#define CLK_DPU_SPI_ACLK	55
+#define CLK_V2D			56
+#define CLK_APMU_NUM		57
+
+#endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */
-- 
2.46.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/2] clk: spacemit: Add clock support for Spacemit K1 SoC
  2024-08-31 15:45 [PATCH 0/2] Add clock controller support for Spacemit K1 Haylen Chu
  2024-08-31 15:47 ` [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC Haylen Chu
@ 2024-08-31 15:47 ` Haylen Chu
  1 sibling, 0 replies; 9+ messages in thread
From: Haylen Chu @ 2024-08-31 15:47 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-clk, devicetree, linux-kernel, Haylen Chu

The clock tree of K1 SoC contains three main types of clock hardware
(PLL/DDN/MIX) and is managed by several independent controllers in
different SoC parts (APBC, APBS and etc.), thus different compatible
strings are added to distinguish them.

Some controllers may share IO region with reset controller and other low
speed peripherals like watchdog, so all register operations are done
through regmap to avoid competition.

Signed-off-by: Haylen Chu <heylenay@outlook.com>
---
 drivers/clk/Kconfig                 |   1 +
 drivers/clk/Makefile                |   1 +
 drivers/clk/spacemit/Kconfig        |  10 +
 drivers/clk/spacemit/Makefile       |   4 +
 drivers/clk/spacemit/ccu-spacemit.c | 594 ++++++++++++++++++++++++++++
 drivers/clk/spacemit/ccu_common.h   |  55 +++
 drivers/clk/spacemit/ccu_ddn.c      | 167 ++++++++
 drivers/clk/spacemit/ccu_ddn.h      |  84 ++++
 drivers/clk/spacemit/ccu_mix.c      | 338 ++++++++++++++++
 drivers/clk/spacemit/ccu_mix.h      | 349 ++++++++++++++++
 drivers/clk/spacemit/ccu_pll.c      | 229 +++++++++++
 drivers/clk/spacemit/ccu_pll.h      |  82 ++++
 12 files changed, 1914 insertions(+)
 create mode 100644 drivers/clk/spacemit/Kconfig
 create mode 100644 drivers/clk/spacemit/Makefile
 create mode 100644 drivers/clk/spacemit/ccu-spacemit.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 983ef4f36d8c..04f4cb2d1127 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -490,6 +490,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 f793a16cad40..2b2532ebf5d0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -119,6 +119,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG)	+= samsung/
 obj-$(CONFIG_CLK_SIFIVE)		+= sifive/
 obj-y					+= socfpga/
 obj-y					+= sophgo/
+obj-y					+= spacemit/
 obj-$(CONFIG_PLAT_SPEAR)		+= spear/
 obj-y					+= sprd/
 obj-$(CONFIG_ARCH_STI)			+= st/
diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig
new file mode 100644
index 000000000000..ce49568eec96
--- /dev/null
+++ b/drivers/clk/spacemit/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SPACEMIT_CCU
+	tristate "Clock support for Spacemit SoCs"
+	depends on ARCH_SPACEMIT || COMPILE_TEST
+	default y
+	select MFD_SYSCON
+	help
+	  This driver supports clock controllers integrated in Spacemit K1
+	  SoC. If unsure, say N.
diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile
new file mode 100644
index 000000000000..2bcd5021670b
--- /dev/null
+++ b/drivers/clk/spacemit/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SPACEMIT_CCU)	+= ccu-spacemit.o
+obj-$(CONFIG_SPACEMIT_CCU)	+= ccu_pll.o ccu_mix.o ccu_ddn.o
diff --git a/drivers/clk/spacemit/ccu-spacemit.c b/drivers/clk/spacemit/ccu-spacemit.c
new file mode 100644
index 000000000000..da557086824f
--- /dev/null
+++ b/drivers/clk/spacemit/ccu-spacemit.c
@@ -0,0 +1,594 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+
+#include <linux/delay.h>
+#include <dt-bindings/clock/spacemit,ccu.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_pll.h"
+#include "ccu_mix.h"
+#include "ccu_ddn.h"
+
+/*	APBS register offset	*/
+/*	pll1	*/
+#define APB_SPARE1_REG			0x100
+#define APB_SPARE2_REG			0x104
+#define APB_SPARE3_REG			0x108
+/*	pll2	*/
+#define APB_SPARE7_REG			0x118
+#define APB_SPARE8_REG			0x11c
+#define APB_SPARE9_REG			0x120
+/*	pll3	*/
+#define APB_SPARE10_REG			0x124
+#define APB_SPARE11_REG			0x128
+#define APB_SPARE12_REG			0x12c
+
+/* MPMU register offset */
+#define MPMU_POSR			0x10
+#define POSR_PLL1_LOCK			BIT(27)
+#define POSR_PLL2_LOCK			BIT(28)
+#define POSR_PLL3_LOCK			BIT(29)
+
+#define MPMU_WDTPCR			0x200
+#define MPMU_RIPCCR			0x210
+#define MPMU_ACGR			0x1024
+#define MPMU_SUCCR			0x14
+#define MPMU_ISCCR			0x44
+#define MPMU_SUCCR_1			0x10b0
+#define MPMU_APBCSCR			0x1050
+
+/* APBC register offset */
+#define APBC_UART1_CLK_RST		0x0
+#define APBC_UART2_CLK_RST		0x4
+#define APBC_UART3_CLK_RST		0x24
+#define APBC_UART4_CLK_RST		0x70
+#define APBC_UART5_CLK_RST		0x74
+#define APBC_UART6_CLK_RST		0x78
+#define APBC_UART7_CLK_RST		0x94
+#define APBC_UART8_CLK_RST		0x98
+#define APBC_UART9_CLK_RST		0x9c
+
+/* APMU register offset */
+#define APMU_CCI550_CLK_CTRL		0x300
+#define APMU_CPU_C0_CLK_CTRL		0x38C
+#define APMU_CPU_C1_CLK_CTRL		0x390
+
+/*	APBS clocks start	*/
+
+static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = {
+	CCU_PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000),
+	CCU_PLL_RATE(3200000000UL, 0x67, 0xdd, 0x50, 0x00, 0x43, 0xeaaaab),
+	CCU_PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd),
+	CCU_PLL_RATE(2800000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3a, 0x155555),
+};
+
+static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = {
+	CCU_PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000),
+	CCU_PLL_RATE(3200000000UL, 0x67, 0xdd, 0x50, 0x00, 0x43, 0xeaaaab),
+	CCU_PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd),
+};
+
+static CCU_PLL_DEFINE(pll2, "pll2", pll2_rate_tbl,
+		      APB_SPARE7_REG, APB_SPARE8_REG, APB_SPARE9_REG,
+		      MPMU_POSR, POSR_PLL2_LOCK, 0);
+static CCU_PLL_DEFINE(pll3, "pll3", pll3_rate_tbl,
+		      APB_SPARE10_REG, APB_SPARE11_REG, APB_SPARE12_REG,
+		      MPMU_POSR, POSR_PLL3_LOCK, 0);
+
+static CCU_GATE_FACTOR_DEFINE(pll1_d2, "pll1_d2", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(1), BIT(1), 0, 2, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d3, "pll1_d3", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(2), BIT(2), 0, 3, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d4, "pll1_d4", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(3), BIT(3), 0, 4, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d5, "pll1_d5", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(4), BIT(4), 0, 5, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d6, "pll1_d6", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(5), BIT(5), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d7, "pll1_d7", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(6), BIT(6), 0, 7, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d8, "pll1_d8", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(7), BIT(7), 0, 8, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d11_223p4, "pll1_d11_223p4",
+			      "pll1_2457p6_vco", APB_SPARE2_REG,
+			      BIT(15), BIT(15), 0, 11, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d13_189, "pll1_d13_189", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(16), BIT(16), 0, 13, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d23_106p8, "pll1_d23_106p8",
+			      "pll1_2457p6_vco", APB_SPARE2_REG,
+			      BIT(20), BIT(20), 0, 23, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d64_38p4, "pll1_d64_38p4", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(0), BIT(0), 0, 64, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_aud_245p7, "pll1_aud_245p7",
+			      "pll1_2457p6_vco", APB_SPARE2_REG,
+			      BIT(10), BIT(10), 0, 10, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_aud_24p5, "pll1_aud_24p5", "pll1_2457p6_vco",
+			      APB_SPARE2_REG,
+			      BIT(11), BIT(11), 0, 100, 1, 0);
+
+static CCU_GATE_FACTOR_DEFINE(pll2_d1, "pll2_d1", "pll2", APB_SPARE8_REG,
+			      BIT(0), BIT(0), 0, 1, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d2, "pll2_d2", "pll2", APB_SPARE8_REG,
+			      BIT(1), BIT(1), 0, 2, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d3, "pll2_d3", "pll2", APB_SPARE8_REG,
+			      BIT(2), BIT(2), 0, 3, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d4, "pll2_d4", "pll2", APB_SPARE8_REG,
+			      BIT(3), BIT(3), 0, 4, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d5, "pll2_d5", "pll2", APB_SPARE8_REG,
+			      BIT(4), BIT(4), 0, 5, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d6, "pll2_d6", "pll2", APB_SPARE8_REG,
+			      BIT(5), BIT(5), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d7, "pll2_d7", "pll2", APB_SPARE8_REG,
+			      BIT(6), BIT(6), 0, 7, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll2_d8, "pll2_d8", "pll2", APB_SPARE8_REG,
+			      BIT(7), BIT(7), 0, 8, 1, 0);
+
+static CCU_GATE_FACTOR_DEFINE(pll3_d1, "pll3_d1", "pll3", APB_SPARE11_REG,
+			      BIT(0), BIT(0), 0, 1, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d2, "pll3_d2", "pll3", APB_SPARE11_REG,
+			      BIT(1), BIT(1), 0, 2, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d3, "pll3_d3", "pll3", APB_SPARE11_REG,
+			      BIT(2), BIT(2), 0, 3, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d4, "pll3_d4", "pll3", APB_SPARE11_REG,
+			      BIT(3), BIT(3), 0, 4, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d5, "pll3_d5", "pll3", APB_SPARE11_REG,
+			      BIT(4), BIT(4), 0, 5, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d6, "pll3_d6", "pll3", APB_SPARE11_REG,
+			      BIT(5), BIT(5), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d7, "pll3_d7", "pll3", APB_SPARE11_REG,
+			      BIT(6), BIT(6), 0, 7, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll3_d8, "pll3_d8", "pll3", APB_SPARE11_REG,
+			      BIT(7), BIT(7), 0, 8, 1, 0);
+
+static CCU_FACTOR_DEFINE(pll3_20, "pll3_20", "pll3_d8", 20, 1);
+static CCU_FACTOR_DEFINE(pll3_40, "pll3_40", "pll3_d8", 10, 1);
+static CCU_FACTOR_DEFINE(pll3_80, "pll3_80", "pll3_d8", 5, 1);
+
+/*	APBS clocks end		*/
+
+/*	MPMU clocks start	*/
+static CCU_GATE_DEFINE(pll1_d8_307p2, "pll1_d8_307p2", "pll1_d8",
+	MPMU_ACGR,
+	BIT(13), BIT(13), 0, 0);
+static CCU_FACTOR_DEFINE(pll1_d32_76p8, "pll1_d32_76p8", "pll1_d8_307p2",
+			 4, 1);
+static CCU_FACTOR_DEFINE(pll1_d40_61p44, "pll1_d40_61p44", "pll1_d8_307p2",
+			 5, 1);
+static CCU_FACTOR_DEFINE(pll1_d16_153p6, "pll1_d16_153p6", "pll1_d8",
+			 2, 1);
+static CCU_GATE_FACTOR_DEFINE(pll1_d24_102p4, "pll1_d24_102p4", "pll1_d8",
+			      MPMU_ACGR,
+			      BIT(12), BIT(12), 0, 3, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d48_51p2, "pll1_d48_51p2", "pll1_d8",
+			      MPMU_ACGR,
+			      BIT(7), BIT(7), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d48_51p2_ap, "pll1_d48_51p2_ap", "pll1_d8",
+			      MPMU_ACGR,
+			      BIT(11), BIT(11), 0, 6, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_m3d128_57p6, "pll1_m3d128_57p6", "pll1_d8",
+			      MPMU_ACGR,
+			      BIT(8), BIT(8), 0, 16, 3, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d96_25p6, "pll1_d96_25p6", "pll1_d8",
+			      MPMU_ACGR,
+			      BIT(4), BIT(4), 0, 12, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d192_12p8, "pll1_d192_12p8", "pll1_d8",
+			      MPMU_ACGR,
+			      BIT(3), BIT(3), 0, 24, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d192_12p8_wdt, "pll1_d192_12p8_wdt",
+			      "pll1_d8", MPMU_ACGR,
+			      BIT(19), BIT(19), 0x0, 24, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d384_6p4, "pll1_d384_6p4", "pll1_d8",
+			      MPMU_ACGR,
+			      BIT(2), BIT(2), 0, 48, 1, 0);
+static CCU_FACTOR_DEFINE(pll1_d768_3p2, "pll1_d768_3p2", "pll1_d384_6p4",
+			 2, 1);
+static CCU_FACTOR_DEFINE(pll1_d1536_1p6, "pll1_d1536_1p6", "pll1_d384_6p4",
+			 4, 1);
+static CCU_FACTOR_DEFINE(pll1_d3072_0p8, "pll1_d3072_0p8", "pll1_d384_6p4",
+			 8, 1);
+
+static CCU_FACTOR_DEFINE(pll1_d7_351p08, "pll1_d7_351p08", "pll1_d7",
+			 1, 1);
+
+static CCU_GATE_DEFINE(pll1_d6_409p6, "pll1_d6_409p6", "pll1_d6",
+		       MPMU_ACGR,
+		       BIT(0), BIT(0), 0, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d12_204p8, "pll1_d12_204p8", "pll1_d6",
+			      MPMU_ACGR,
+			      BIT(5), BIT(5), 0, 2, 1, 0);
+
+static CCU_GATE_DEFINE(pll1_d5_491p52, "pll1_d5_491p52", "pll1_d5",
+		       MPMU_ACGR, BIT(21), BIT(21), 0, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d10_245p76, "pll1_d10_245p76", "pll1_d5",
+			      MPMU_ACGR,
+			      BIT(18), BIT(18), 0, 2, 1, 0);
+
+static CCU_GATE_DEFINE(pll1_d4_614p4, "pll1_d4_614p4", "pll1_d4",
+		       MPMU_ACGR,
+		       BIT(15), BIT(15), 0, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d52_47p26, "pll1_d52_47p26", "pll1_d4",
+			      MPMU_ACGR,
+			      BIT(10), BIT(10), 0, 13, 1, 0);
+static CCU_GATE_FACTOR_DEFINE(pll1_d78_31p5, "pll1_d78_31p5", "pll1_d4",
+			      MPMU_ACGR,
+			      BIT(6), BIT(6), 0, 39, 2, 0);
+
+static CCU_GATE_DEFINE(pll1_d3_819p2, "pll1_d3_819p2", "pll1_d3",
+		       MPMU_ACGR,
+		       BIT(14), BIT(14), 0, 0);
+
+static CCU_GATE_DEFINE(pll1_d2_1228p8, "pll1_d2_1228p8", "pll1_d2",
+		       MPMU_ACGR,
+		       BIT(16), BIT(16), 0, 0);
+
+static struct ccu_ddn_info uart_ddn_mask_info = {
+	.factor		= 2,
+	.num_mask	= 0x1fff,
+	.den_mask	= 0x1fff,
+	.num_shift	= 16,
+	.den_shift	= 0,
+};
+static struct ccu_ddn_tbl slow_uart1_tbl[] = {
+	{ .num = 125, .den = 24 },
+};
+static struct ccu_ddn_tbl slow_uart2_tbl[] = {
+	{ .num = 6144, .den = 960 },
+};
+static CCU_GATE_NO_PARENT_DEFINE(slow_uart, "slow_uart",
+				 MPMU_ACGR,
+				 BIT(1), BIT(1), 0, 0);
+static CCU_DDN_DEFINE(slow_uart1_14p74, "slow_uart1_14p74", "pll1_d16_153p6",
+		      &uart_ddn_mask_info, slow_uart1_tbl,
+		      MPMU_SUCCR, 0);
+static CCU_DDN_DEFINE(slow_uart2_48, "slow_uart2_48", "pll1_d4_614p4",
+		      &uart_ddn_mask_info, slow_uart2_tbl,
+		      MPMU_SUCCR_1, 0);
+/*	MPMU clocks end		*/
+
+/*	APBC clocks start	*/
+static const char * const uart_clk_parents[] = {
+	"pll1_m3d128_57p6", "slow_uart1_14p74", "slow_uart2_48",
+};
+static CCU_MUX_GATE_DEFINE(uart0_clk, "uart0_clk", uart_clk_parents,
+			   APBC_UART1_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart2_clk, "uart2_clk", uart_clk_parents,
+			   APBC_UART2_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart3_clk, "uart3_clk", uart_clk_parents,
+			   APBC_UART3_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart4_clk, "uart4_clk", uart_clk_parents,
+			   APBC_UART4_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart5_clk, "uart5_clk", uart_clk_parents,
+			   APBC_UART5_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart6_clk, "uart6_clk", uart_clk_parents,
+			   APBC_UART6_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart7_clk, "uart7_clk", uart_clk_parents,
+			   APBC_UART7_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart8_clk, "uart8_clk", uart_clk_parents,
+			   APBC_UART8_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+static CCU_MUX_GATE_DEFINE(uart9_clk, "uart9_clk", uart_clk_parents,
+			   APBC_UART9_CLK_RST,
+			   4, 3, 0x3, 0x3, 0x0,
+			   0);
+/*	APBC clocks end		*/
+
+/*	APMU clocks start	*/
+static const char * const cci550_clk_parents[] = {
+	"pll1_d5_491p52", "pll1_d4_614p4", "pll1_d3_819p2", "pll2_d3"
+};
+static CCU_DIV_FC_MUX_DEFINE(cci550_clk, "cci550_clk", cci550_clk_parents,
+			     APMU_CCI550_CLK_CTRL,
+			     8, 3, BIT(12), 0, 2, CLK_IS_CRITICAL);
+
+static const char * const cpu_c0_hi_clk_parents[] = { "pll3_d2", "pll3_d1" };
+static CCU_MUX_DEFINE(cpu_c0_hi_clk, "cpu_c0_hi_clk", cpu_c0_hi_clk_parents,
+		      APMU_CPU_C0_CLK_CTRL,
+		      13, 1, 0);
+static const char * const cpu_c0_clk_parents[] = {
+	"pll1_d4_614p4", "pll1_d3_819p2", "pll1_d6_409p6", "pll1_d5_491p52",
+	"pll1_d2_1228p8", "pll3_d3", "pll2_d3", "cpu_c0_hi_clk"
+};
+static CCU_MUX_FC_DEFINE(cpu_c0_core_clk, "cpu_c0_core_clk", cpu_c0_clk_parents,
+			 APMU_CPU_C0_CLK_CTRL,
+			 BIT(12), 0, 3, CLK_IS_CRITICAL);
+static CCU_DIV_DEFINE(cpu_c0_ace_clk, "cpu_c0_ace_clk", "cpu_c0_core_clk",
+		      APMU_CPU_C0_CLK_CTRL,
+		      6, 3, CLK_IS_CRITICAL);
+static CCU_DIV_DEFINE(cpu_c0_tcm_clk, "cpu_c0_tcm_clk", "cpu_c0_core_clk",
+		      APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL);
+
+static const char * const cpu_c1_hi_clk_parents[] = { "pll3_d2", "pll3_d1" };
+static CCU_MUX_DEFINE(cpu_c1_hi_clk, "cpu_c1_hi_clk", cpu_c1_hi_clk_parents,
+		      APMU_CPU_C1_CLK_CTRL,
+		      13, 1, CLK_IS_CRITICAL);
+static const char * const cpu_c1_clk_parents[] = {
+	"pll1_d4_614p4", "pll1_d3_819p2", "pll1_d6_409p6", "pll1_d5_491p52",
+	"pll1_d2_1228p8", "pll3_d3", "pll2_d3", "cpu_c1_hi_clk"
+};
+static CCU_MUX_FC_DEFINE(cpu_c1_core_clk, "cpu_c1_core_clk", cpu_c1_clk_parents,
+			 APMU_CPU_C1_CLK_CTRL,
+			 BIT(12), 0, 3, CLK_IS_CRITICAL);
+static CCU_DIV_DEFINE(cpu_c1_ace_clk, "cpu_c1_ace_clk", "cpu_c1_core_clk",
+		      APMU_CPU_C1_CLK_CTRL,
+		      6, 3, CLK_IS_CRITICAL);
+/*	APMU clocks end		*/
+
+static struct clk_hw_onecell_data spacemit_ccu_apbs_clks = {
+	.hws = {
+		[CLK_PLL2]		= &pll2.common.hw,
+		[CLK_PLL3]		= &pll3.common.hw,
+		[CLK_PLL1_D2]		= &pll1_d2.common.hw,
+		[CLK_PLL1_D3]		= &pll1_d3.common.hw,
+		[CLK_PLL1_D4]		= &pll1_d4.common.hw,
+		[CLK_PLL1_D5]		= &pll1_d5.common.hw,
+		[CLK_PLL1_D6]		= &pll1_d6.common.hw,
+		[CLK_PLL1_D7]		= &pll1_d7.common.hw,
+		[CLK_PLL1_D8]		= &pll1_d8.common.hw,
+		[CLK_PLL1_D11]		= &pll1_d11_223p4.common.hw,
+		[CLK_PLL1_D13]		= &pll1_d13_189.common.hw,
+		[CLK_PLL1_D23]		= &pll1_d23_106p8.common.hw,
+		[CLK_PLL1_D64]		= &pll1_d64_38p4.common.hw,
+		[CLK_PLL1_D10_AUD]	= &pll1_aud_245p7.common.hw,
+		[CLK_PLL1_D100_AUD]	= &pll1_aud_24p5.common.hw,
+		[CLK_PLL2_D1]		= &pll2_d1.common.hw,
+		[CLK_PLL2_D2]		= &pll2_d2.common.hw,
+		[CLK_PLL2_D3]		= &pll2_d3.common.hw,
+		[CLK_PLL2_D3]		= &pll2_d4.common.hw,
+		[CLK_PLL2_D5]		= &pll2_d5.common.hw,
+		[CLK_PLL2_D6]		= &pll2_d6.common.hw,
+		[CLK_PLL2_D7]		= &pll2_d7.common.hw,
+		[CLK_PLL2_D8]		= &pll2_d8.common.hw,
+		[CLK_PLL3_D1]		= &pll3_d1.common.hw,
+		[CLK_PLL3_D2]		= &pll3_d2.common.hw,
+		[CLK_PLL3_D3]		= &pll3_d3.common.hw,
+		[CLK_PLL3_D4]		= &pll3_d4.common.hw,
+		[CLK_PLL3_D5]		= &pll3_d5.common.hw,
+		[CLK_PLL3_D6]		= &pll3_d6.common.hw,
+		[CLK_PLL3_D7]		= &pll3_d7.common.hw,
+		[CLK_PLL3_D8]		= &pll3_d8.common.hw,
+		[CLK_PLL3_80]		= &pll3_80.common.hw,
+		[CLK_PLL3_40]		= &pll3_40.common.hw,
+		[CLK_PLL3_20]		= &pll3_20.common.hw,
+
+	},
+	.num = CLK_APBS_NUM,
+};
+
+static struct clk_hw_onecell_data spacemit_ccu_mpmu_clks = {
+	.hws = {
+		[CLK_PLL1_307P2]	= &pll1_d8_307p2.common.hw,
+		[CLK_PLL1_76P8]		= &pll1_d32_76p8.common.hw,
+		[CLK_PLL1_61P44]	= &pll1_d40_61p44.common.hw,
+		[CLK_PLL1_153P6]	= &pll1_d16_153p6.common.hw,
+		[CLK_PLL1_102P4]	= &pll1_d24_102p4.common.hw,
+		[CLK_PLL1_51P2]		= &pll1_d48_51p2.common.hw,
+		[CLK_PLL1_51P2_AP]	= &pll1_d48_51p2_ap.common.hw,
+		[CLK_PLL1_57P6]		= &pll1_m3d128_57p6.common.hw,
+		[CLK_PLL1_25P6]		= &pll1_d96_25p6.common.hw,
+		[CLK_PLL1_12P8]		= &pll1_d192_12p8.common.hw,
+		[CLK_PLL1_12P8_WDT]	= &pll1_d192_12p8_wdt.common.hw,
+		[CLK_PLL1_6P4]		= &pll1_d384_6p4.common.hw,
+		[CLK_PLL1_3P2]		= &pll1_d768_3p2.common.hw,
+		[CLK_PLL1_1P6]		= &pll1_d1536_1p6.common.hw,
+		[CLK_PLL1_0P8]		= &pll1_d3072_0p8.common.hw,
+		[CLK_PLL1_351]		= &pll1_d7_351p08.common.hw,
+		[CLK_PLL1_409P6]	= &pll1_d6_409p6.common.hw,
+		[CLK_PLL1_204P8]	= &pll1_d12_204p8.common.hw,
+		[CLK_PLL1_491]		= &pll1_d5_491p52.common.hw,
+		[CLK_PLL1_245P76]	= &pll1_d10_245p76.common.hw,
+		[CLK_PLL1_614]		= &pll1_d4_614p4.common.hw,
+		[CLK_PLL1_47P26]	= &pll1_d52_47p26.common.hw,
+		[CLK_PLL1_31P5]		= &pll1_d78_31p5.common.hw,
+		[CLK_PLL1_819]		= &pll1_d3_819p2.common.hw,
+		[CLK_PLL1_1228]		= &pll1_d2_1228p8.common.hw,
+		[CLK_SLOW_UART]		= &slow_uart.common.hw,
+		[CLK_SLOW_UART1]	= &slow_uart1_14p74.common.hw,
+		[CLK_SLOW_UART2]	= &slow_uart2_48.common.hw,
+	},
+	.num = CLK_SLOW_UART2 + 1,
+};
+
+static struct clk_hw_onecell_data spacemit_ccu_apbc_clks = {
+	.hws = {
+		[CLK_UART0]		= &uart0_clk.common.hw,
+		[CLK_UART2]		= &uart2_clk.common.hw,
+		[CLK_UART3]		= &uart3_clk.common.hw,
+		[CLK_UART4]		= &uart4_clk.common.hw,
+		[CLK_UART5]		= &uart5_clk.common.hw,
+		[CLK_UART6]		= &uart6_clk.common.hw,
+		[CLK_UART7]		= &uart7_clk.common.hw,
+		[CLK_UART8]		= &uart8_clk.common.hw,
+		[CLK_UART9]		= &uart9_clk.common.hw,
+	},
+	.num = CLK_UART9 + 1,
+};
+
+static struct clk_hw_onecell_data spacemit_ccu_apmu_clks = {
+	.hws = {
+		[CLK_CCI550]		= &cci550_clk.common.hw,
+		[CLK_CPU_C0_HI]		= &cpu_c0_hi_clk.common.hw,
+		[CLK_CPU_C0_CORE]	= &cpu_c0_core_clk.common.hw,
+		[CLK_CPU_C0_ACE]	= &cpu_c0_ace_clk.common.hw,
+		[CLK_CPU_C0_TCM]	= &cpu_c0_tcm_clk.common.hw,
+		[CLK_CPU_C1_HI]		= &cpu_c1_hi_clk.common.hw,
+		[CLK_CPU_C1_CORE]	= &cpu_c1_core_clk.common.hw,
+		[CLK_CPU_C1_ACE]	= &cpu_c1_ace_clk.common.hw,
+	},
+	.num = CLK_CPU_C1_ACE + 1,
+};
+
+struct spacemit_ccu_data {
+	struct clk_hw_onecell_data *hw_clks;
+	bool need_pll_lock;
+};
+
+struct spacemit_ccu_priv {
+	const struct spacemit_ccu_data *data;
+	struct regmap *base;
+	struct regmap *lock_base;
+	spinlock_t lock;
+};
+
+static int spacemit_ccu_register(struct device *dev,
+				 struct spacemit_ccu_priv *priv)
+{
+	const struct spacemit_ccu_data *data = priv->data;
+	int i, ret;
+
+	for (i = 0; i < data->hw_clks->num; i++) {
+		struct clk_hw *hw = data->hw_clks->hws[i];
+		struct ccu_common *common;
+		const char *name;
+
+		if (!hw)
+			continue;
+
+		common = hw_to_ccu_common(hw);
+		name = hw->init->name;
+
+		common->lock		= &priv->lock;
+		common->base		= priv->base;
+		common->lock_base	= priv->lock_base;
+
+		ret = devm_clk_hw_register(dev, hw);
+		if (ret) {
+			dev_err(dev, "Cannot register clock %d - %s\n",
+				i, name);
+			return ret;
+		}
+	}
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   data->hw_clks);
+}
+
+static int spacemit_ccu_probe(struct platform_device *pdev)
+{
+	const struct spacemit_ccu_data *data;
+	struct regmap *base_map, *lock_map;
+	struct device *dev = &pdev->dev;
+	struct spacemit_ccu_priv *priv;
+	struct device_node *parent;
+	int ret;
+
+	data = of_device_get_match_data(dev);
+	if (WARN_ON(!data))
+		return -EINVAL;
+
+	parent   = of_get_parent(dev->of_node);
+	base_map = syscon_node_to_regmap(parent);
+	of_node_put(parent);
+
+	if (IS_ERR(base_map))
+		return dev_err_probe(dev, PTR_ERR(base_map),
+				     "failed to get regmap\n");
+
+	if (data->need_pll_lock) {
+		lock_map = syscon_regmap_lookup_by_phandle(dev->of_node,
+							   "spacemit,mpmu");
+		if (IS_ERR(lock_map))
+			return dev_err_probe(dev, PTR_ERR(lock_map),
+					     "failed to get lock regmap\n");
+	}
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->data	= data;
+	priv->base	= base_map;
+	priv->lock_base	= lock_map;
+	spin_lock_init(&priv->lock);
+
+	ret = spacemit_ccu_register(dev, priv);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register clocks");
+
+	return 0;
+}
+
+static const struct spacemit_ccu_data spacemit_ccu_apbs_data = {
+	.need_pll_lock	= true,
+	.hw_clks	= &spacemit_ccu_apbs_clks,
+};
+
+static const struct spacemit_ccu_data spacemit_ccu_mpmu_data = {
+	.need_pll_lock	= false,
+	.hw_clks	= &spacemit_ccu_mpmu_clks,
+};
+
+static const struct spacemit_ccu_data spacemit_ccu_apbc_data = {
+	.need_pll_lock	= false,
+	.hw_clks	= &spacemit_ccu_apbc_clks,
+};
+
+static const struct spacemit_ccu_data spacemit_ccu_apmu_data = {
+	.need_pll_lock	= false,
+	.hw_clks	= &spacemit_ccu_apmu_clks,
+};
+
+static const struct of_device_id of_spacemit_ccu_match[] = {
+	{
+		.compatible	= "spacemit,ccu-apbs",
+		.data		= &spacemit_ccu_apbs_data,
+	},
+	{
+		.compatible	= "spacemit,ccu-mpmu",
+		.data		= &spacemit_ccu_mpmu_data,
+	},
+	{
+		.compatible	= "spacemit,ccu-apbc",
+		.data		= &spacemit_ccu_apbc_data,
+	},
+	{
+		.compatible	= "spacemit,ccu-apmu",
+		.data		= &spacemit_ccu_apmu_data,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, of_spacemit_ccu_match);
+
+static struct platform_driver spacemit_ccu_driver = {
+	.driver = {
+		.name		= "spacemit,ccu",
+		.of_match_table = of_spacemit_ccu_match,
+	},
+	.probe	= spacemit_ccu_probe,
+};
+module_platform_driver(spacemit_ccu_driver);
+
+MODULE_DESCRIPTION("Spacemit CCU driver");
+MODULE_AUTHOR("Haylen Chu <heylenay@outlook.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_common.h
new file mode 100644
index 000000000000..c4406099c3fc
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_common.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+
+#ifndef _CCU_COMMON_H_
+#define _CCU_COMMON_H_
+
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+
+enum ccu_div_type {
+	CLK_DIV_TYPE_1REG_NOFC_V1 = 0,
+	CLK_DIV_TYPE_1REG_FC_V2,
+	CLK_DIV_TYPE_2REG_NOFC_V3,
+	CLK_DIV_TYPE_2REG_FC_V4,
+	CLK_DIV_TYPE_1REG_FC_DIV_V5,
+	CLK_DIV_TYPE_1REG_FC_MUX_V6,
+};
+
+struct ccu_common {
+	struct regmap *base;
+	struct regmap *lock_base;
+	spinlock_t *lock;
+
+	enum ccu_div_type reg_type;
+	u32 reg_ctrl;
+	u32 reg_sel;
+	u32 reg_xtc;
+	u32 fc;
+	bool is_pll;
+
+	unsigned long flags;
+	const char *name;
+	const char * const *parent_names;
+	int num_parents;
+
+	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(reg, c, val)	regmap_read((c)->base, (c)->reg_##reg, val)
+#define ccu_write(reg, c, val)	regmap_write((c)->base, (c)->reg_##reg, val)
+#define ccu_update(reg, c, mask, val) \
+	regmap_update_bits((c)->base, (c)->reg_##reg, mask, val)
+#define ccu_poll(reg, c, tmp, cond, sleep, timeout) \
+	regmap_read_poll_timeout_atomic((c)->base, (c)->reg_##reg,	\
+					tmp, cond, sleep, timeout)
+
+#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..bf2a790c3941
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_ddn.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Spacemit clock type ddn
+ *
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+
+#include "ccu_ddn.h"
+
+#define ddn_read_sel(common, val)	ccu_read(sel, common, val)
+#define ddn_read_ctrl(common, val)	ccu_read(ctrl, common, val)
+#define ddn_update_sel(common, m, v)	ccu_update(sel, common, m, v)
+#define ddn_update_ctrl(common, m, v)	ccu_update(ctrl, common, m, v)
+
+/*
+ * It is M/N clock
+ *
+ * Fout from synthesizer can be given from two equations:
+ * numerator/denominator = Fin / (Fout * factor)
+ */
+static void ccu_ddn_disable(struct clk_hw *hw)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_common *common = &ddn->common;
+	unsigned long flags;
+
+	if (!ddn->gate)
+		return;
+
+	spin_lock_irqsave(common->lock, flags);
+
+	ddn_update_sel(common, ddn->gate, 0);
+
+	spin_unlock_irqrestore(common->lock, flags);
+}
+
+static int ccu_ddn_enable(struct clk_hw *hw)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_common *common = &ddn->common;
+	unsigned long flags;
+
+	if (!ddn->gate)
+		return 0;
+
+	spin_lock_irqsave(common->lock, flags);
+
+	ddn_update_sel(common, ddn->gate, ddn->gate);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	return 0;
+}
+
+static int ccu_ddn_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_common *common = &ddn->common;
+	u32 tmp;
+
+	if (!ddn->gate)
+		return 1;
+
+	ddn_read_sel(common, &tmp);
+
+	return tmp & ddn->gate;
+}
+
+static long clk_ddn_round_rate(struct clk_hw *hw, unsigned long drate,
+			       unsigned long *prate)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_ddn_config *params = &ddn->ddn;
+	unsigned long rate = 0, prev_rate;
+	unsigned long result;
+	int i;
+
+	for (i = 0; i < params->tbl_size; i++) {
+		prev_rate = rate;
+		rate = (((*prate / 10000) * params->tbl[i].den) /
+			(params->tbl[i].num * params->info->factor)) * 10000;
+		if (rate > drate)
+			break;
+	}
+
+	if ((i == 0) || (i == params->tbl_size)) {
+		result = rate;
+	} else {
+		if ((drate - prev_rate) > (rate - drate))
+			result = rate;
+		else
+			result = prev_rate;
+	}
+
+	return result;
+}
+
+static unsigned long clk_ddn_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_ddn_config *params = &ddn->ddn;
+	unsigned int val, num, den;
+	unsigned long rate;
+
+	ddn_read_ctrl(&ddn->common, &val);
+
+	num = (val >> params->info->num_shift) & params->info->num_mask;
+	den = (val >> params->info->den_shift) & params->info->den_mask;
+
+	if (!den)
+		return 0;
+
+	rate = ((parent_rate / 10000)  * den) / (num * params->info->factor);
+	rate *= 10000;
+
+	return rate;
+}
+
+/* Configures new clock rate*/
+static int clk_ddn_set_rate(struct clk_hw *hw, unsigned long drate,
+			    unsigned long prate)
+{
+	struct ccu_ddn *ddn = hw_to_ccu_ddn(hw);
+	struct ccu_ddn_config *params = &ddn->ddn;
+	struct ccu_ddn_info *info = params->info;
+	unsigned long prev_rate, rate = 0;
+	unsigned long flags;
+	int i;
+
+	for (i = 0; i < params->tbl_size; i++) {
+		prev_rate = rate;
+		rate = ((prate / 10000) * params->tbl[i].den) /
+		       (params->tbl[i].num * info->factor);
+		rate *= 10000;
+
+		if (rate > drate)
+			break;
+	}
+
+	if (i > 0)
+		i--;
+
+	spin_lock_irqsave(ddn->common.lock, flags);
+
+	ddn_update_ctrl(&ddn->common,
+			info->num_mask | info->den_mask,
+			(params->tbl[i].num << info->num_shift) |
+			(params->tbl[i].den << info->den_shift));
+
+	spin_unlock_irqrestore(ddn->common.lock, flags);
+
+	return 0;
+}
+
+const struct clk_ops spacemit_ccu_ddn_ops = {
+	.disable	= ccu_ddn_disable,
+	.enable		= ccu_ddn_enable,
+	.is_enabled	= ccu_ddn_is_enabled,
+	.recalc_rate	= clk_ddn_recalc_rate,
+	.round_rate	= clk_ddn_round_rate,
+	.set_rate	= clk_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..ac9c397c7cc9
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_ddn.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenayy@outlook.com>
+ */
+
+#ifndef _CCU_DDN_H_
+#define _CCU_DDN_H_
+
+
+#include <linux/spinlock_types.h>
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+struct ccu_ddn_tbl {
+	unsigned int num;
+	unsigned int den;
+};
+
+struct ccu_ddn_info {
+	unsigned int factor;
+	unsigned int num_mask;
+	unsigned int den_mask;
+	unsigned int num_shift;
+	unsigned int den_shift;
+};
+
+struct ccu_ddn_config {
+	struct ccu_ddn_info *info;
+	struct ccu_ddn_tbl *tbl;
+	u32 tbl_size;
+};
+
+struct ccu_ddn {
+	struct ccu_ddn_config  ddn;
+	struct ccu_common	common;
+	u32 gate;
+};
+
+#define CCU_DDN_CONFIG(_info, _table)					\
+	{								\
+		.info		= (struct ccu_ddn_info *)_info,		\
+		.tbl		= (struct ccu_ddn_tbl *)&_table,	\
+		.tbl_size	= ARRAY_SIZE(_table),			\
+	}
+
+#define CCU_DDN_DEFINE(_struct, _name, _parent, _info, _table,		\
+		       _reg_ctrl, _flags)				\
+	struct ccu_ddn _struct = {					\
+		.ddn	= CCU_DDN_CONFIG(_info, _table),		\
+		.common = {						\
+			.reg_ctrl = _reg_ctrl,				\
+			.hw.init  = CLK_HW_INIT(_name, _parent,		\
+					       &spacemit_ccu_ddn_ops,	\
+					       _flags),			\
+		}							\
+	}
+
+#define CCU_DDN_GATE_DEFINE(_struct, _name, _parent, _info, _table,	\
+			    _reg_ddn, _reg_gate, _gate_mask, _flags)	\
+	struct ccu_ddn _struct = {					\
+		.ddn	= CCU_DDN_CONFIG(_info, _table),		\
+		.common = {						\
+			.reg_ctrl	= _reg_ddn,			\
+			.reg_sel	= _reg_gate,			\
+			.hw.init = CLK_HW_INIT(_name, _parent,		\
+					       &spacemit_ccu_ddn_ops,	\
+					       _flags),			\
+		}							\
+		.gate	= _gate_mask,					\
+	}
+
+
+static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw)
+{
+	struct ccu_common *common = 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..17182de761f6
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_mix.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Spacemit clock type mix(div/mux/gate/factor)
+ *
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "ccu_mix.h"
+
+#define MIX_TIMEOUT	10000
+
+#define mix_read_sel(c, val)		ccu_read(sel, c, val)
+#define mix_read_ctrl(c, val)		ccu_read(ctrl, c, val)
+#define mix_update_sel(c, m, v)		ccu_update(sel, c, m, v)
+#define mix_update_ctrl(c, m, v)	ccu_update(ctrl, c, m, v)
+
+#define mix_hwparam_in_sel(c) \
+	((c)->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || \
+	 (c)->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
+
+static void ccu_mix_disable(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_gate_config *gate = mix->gate;
+	unsigned long flags = 0;
+
+	if (!gate)
+		return;
+
+	spin_lock_irqsave(common->lock, flags);
+
+	if (mix_hwparam_in_sel(common))
+		mix_update_sel(common, gate->gate_mask, gate->val_disable);
+	else
+		mix_update_ctrl(common, gate->gate_mask, gate->val_disable);
+
+	spin_unlock_irqrestore(common->lock, flags);
+}
+
+static int ccu_mix_enable(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_gate_config *gate = mix->gate;
+	u32 val_enable, mask;
+	unsigned long flags;
+	u32 tmp;
+
+	if (!gate)
+		return 0;
+
+	val_enable	= gate->val_enable;
+	mask		= gate->gate_mask;
+
+	spin_lock_irqsave(common->lock, flags);
+
+	if (mix_hwparam_in_sel(common))
+		mix_update_sel(common, mask, val_enable);
+	else
+		mix_update_ctrl(common, mask, val_enable);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
+	    common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
+		return ccu_poll(sel, common, tmp, (tmp & mask) == val_enable,
+				10, MIX_TIMEOUT);
+	else
+		return ccu_poll(ctrl, common, tmp, (tmp & mask) == val_enable,
+				10, MIX_TIMEOUT);
+}
+
+static int ccu_mix_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_gate_config *gate = mix->gate;
+	unsigned long flags = 0;
+	u32 tmp;
+
+	if (!gate)
+		return 1;
+
+	spin_lock_irqsave(common->lock, flags);
+
+	if (mix_hwparam_in_sel(common))
+		mix_read_sel(common, &tmp);
+	else
+		mix_read_ctrl(common, &tmp);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	return (tmp & gate->gate_mask) == gate->val_enable;
+}
+
+static unsigned long ccu_mix_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_div_config *div = mix->div;
+	unsigned long val;
+	u32 reg;
+
+	if (!div) {
+		if (mix->factor)
+			return parent_rate * mix->factor->mul / mix->factor->div;
+
+		return parent_rate;
+	}
+
+	if (mix_hwparam_in_sel(common))
+		mix_read_sel(common, &reg);
+	else
+		mix_read_ctrl(common, &reg);
+
+	val = reg >> div->shift;
+	val &= (1 << div->width) - 1;
+
+	val = divider_recalc_rate(hw, parent_rate, val, div->table,
+				  div->flags, div->width);
+
+	return val;
+}
+
+
+static int ccu_mix_trigger_fc(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	int ret = 0, timeout = 50;
+	unsigned int val = 0;
+
+	if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
+	    common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
+	    common->reg_type == CLK_DIV_TYPE_1REG_FC_DIV_V5 ||
+	    common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6) {
+		timeout = 50;
+		mix_update_ctrl(common, common->fc, common->fc);
+
+		ret = ccu_poll(ctrl, common, val, !(val & common->fc),
+			       5, MIX_TIMEOUT);
+	}
+
+	return ret;
+}
+
+static int ccu_mix_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	return 0;
+}
+
+static long ccu_mix_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	return rate;
+}
+
+static unsigned long
+ccu_mix_calc_best_rate(struct clk_hw *hw, unsigned long rate, u32 *mux_val,
+		       u32 *div_val)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_div_config *div = mix->div ? mix->div : NULL;
+	struct clk_hw *parent;
+	unsigned long parent_rate = 0, best_rate = 0;
+	u32 i, j, div_max;
+
+	for (i = 0; i < common->num_parents; i++) {
+		parent = clk_hw_get_parent_by_index(hw, i);
+		if (!parent)
+			continue;
+
+		parent_rate = clk_hw_get_rate(parent);
+
+		if (div)
+			div_max = 1 << div->width;
+		else
+			div_max = 1;
+
+		for (j = 1; j <= div_max; j++) {
+			if (abs(parent_rate/j - rate) < abs(best_rate - rate)) {
+				best_rate = DIV_ROUND_UP_ULL(parent_rate, j);
+				*mux_val = i;
+				*div_val = j - 1;
+			}
+		}
+	}
+
+	return best_rate;
+}
+
+static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate,
+			   unsigned long parent_rate)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_div_config *div = mix->div;
+	struct ccu_mux_config *mux = mix->mux;
+	u32 cur_mux, cur_div, mux_val = 0, div_val = 0;
+	unsigned long best_rate = 0;
+	unsigned long flags;
+	int ret = 0, tmp = 0;
+
+	if (!div && !mux)
+		return 0;
+
+	best_rate = ccu_mix_calc_best_rate(hw, rate, &mux_val, &div_val);
+
+	if (mix_hwparam_in_sel(common))
+		mix_read_sel(common, &tmp);
+	else
+		mix_read_ctrl(common, &tmp);
+
+	if (mux) {
+		cur_mux = tmp >> mux->shift;
+		cur_mux &= (1 << mux->width) - 1;
+
+		if (cur_mux != mux_val)
+			clk_hw_set_parent(hw,
+					  clk_hw_get_parent_by_index(hw,
+								     mux_val));
+	}
+
+	if (div) {
+		cur_div = tmp >> div->shift;
+		cur_div &= (1 << div->width) - 1;
+
+		if (cur_div == div_val)
+			return 0;
+	} else {
+		return 0;
+	}
+
+	tmp = GENMASK(div->width + div->shift - 1, div->shift);
+
+	spin_lock_irqsave(common->lock, flags);
+
+	if (mix_hwparam_in_sel(common))
+		mix_update_sel(common, tmp, div_val << div->shift);
+	else
+		mix_update_ctrl(common, tmp, div_val << div->shift);
+
+	if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
+	    common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
+	    common->reg_type == CLK_DIV_TYPE_1REG_FC_DIV_V5)
+		ret = ccu_mix_trigger_fc(hw);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	return ret;
+}
+
+static u8 ccu_mix_get_parent(struct clk_hw *hw)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_mux_config *mux = mix->mux;
+	u32 reg;
+	u8 parent;
+
+	if (!mux)
+		return 0;
+
+	if (mix_hwparam_in_sel(common))
+		mix_read_sel(common, &reg);
+	else
+		mix_read_ctrl(common, &reg);
+
+	parent = reg >> mux->shift;
+	parent &= (1 << mux->width) - 1;
+
+	if (mux->table) {
+		int num_parents = clk_hw_get_num_parents(&common->hw);
+		int i;
+
+		for (i = 0; i < num_parents; i++)
+			if (mux->table[i] == parent)
+				return i;
+	}
+
+	return parent;
+}
+
+static int ccu_mix_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct ccu_mix *mix = hw_to_ccu_mix(hw);
+	struct ccu_common *common = &mix->common;
+	struct ccu_mux_config *mux = mix->mux;
+	unsigned long flags;
+	int ret = 0;
+	u32 mask;
+
+	if (!mux)
+		return 0;
+
+	if (mux->table)
+		index = mux->table[index];
+
+	mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
+
+	spin_lock_irqsave(common->lock, flags);
+
+	if (mix_hwparam_in_sel(common))
+		mix_update_sel(common, mask, index << mux->shift);
+	else
+		mix_update_ctrl(common, mask, index << mux->shift);
+
+	if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
+	    common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
+	    common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6)
+		ret = ccu_mix_trigger_fc(hw);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	return ret;
+}
+
+const struct clk_ops spacemit_ccu_mix_ops = {
+	.disable	 = ccu_mix_disable,
+	.enable		 = ccu_mix_enable,
+	.is_enabled	 = ccu_mix_is_enabled,
+	.get_parent	 = ccu_mix_get_parent,
+	.set_parent	 = ccu_mix_set_parent,
+	.determine_rate  = ccu_mix_determine_rate,
+	.round_rate	 = ccu_mix_round_rate,
+	.recalc_rate	 = ccu_mix_recalc_rate,
+	.set_rate	 = 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..f949afda3ab4
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_mix.h
@@ -0,0 +1,349 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+
+#ifndef _CCU_MIX_H_
+#define _CCU_MIX_H_
+
+#include <linux/clk-provider.h>
+
+#include "ccu_common.h"
+
+struct ccu_gate_config {
+	u32 gate_mask;
+	u32 val_enable;
+	u32 val_disable;
+	u32 flags;
+};
+
+struct ccu_factor_config {
+	u32 div;
+	u32 mul;
+};
+
+struct ccu_mux_config {
+	const u8 *table;
+	u32 flags;
+	u8 shift;
+	u8 width;
+};
+
+struct ccu_div_config {
+	struct clk_div_table *table;
+	u32 max;
+	u32 offset;
+	u32 flags;
+	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(_gate_mask, _val_enable, _val_disable, _flags)		\
+	(&(struct ccu_gate_config) {						\
+		.gate_mask   = _gate_mask,					\
+		.val_enable  = _val_enable,					\
+		.val_disable = _val_disable,					\
+		.flags	     = _flags,						\
+	})
+
+#define CCU_FACTOR_INIT(_div, _mul)					\
+	(&(struct ccu_factor_config) {					\
+		.div = _div,						\
+		.mul = _mul,						\
+	})
+
+
+#define CCU_MUX_INIT(_shift, _width, _table, _flags)			\
+	(&(struct ccu_mux_config) {					\
+		.shift	= _shift,					\
+		.width	= _width,					\
+		.table	= _table,					\
+		.flags	= _flags,					\
+	})
+
+#define CCU_DIV_INIT(_shift, _width, _table, _flags)			\
+	(&(struct ccu_div_config) {					\
+		.shift	= _shift,					\
+		.width	= _width,					\
+		.flags	= _flags,					\
+		.table	= _table,					\
+	})
+
+#define CCU_MIX_INITHW(_name, _parent, _flags) \
+	CLK_HW_INIT(_name, _parent, &spacemit_ccu_mix_ops, _flags)
+
+#define CCU_MIX_ORPHAN_INITHW(_name, _flags) \
+	CLK_HW_INIT_NO_PARENT(_name, &spacemit_ccu_mix_ops, _flags)
+
+#define CCU_MIX_INITHW_PARENTS(_name, _parents, _flags) \
+	CLK_HW_INIT_PARENTS(_name, _parents, &spacemit_ccu_mix_ops, _flags)
+
+#define CCU_GATE_DEFINE(_struct, _name, _parent, _reg, _gate_mask,	\
+			 _val_enable, _val_disable, _flags)		\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.common	= {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init	= CCU_MIX_INITHW(_name, _parent,	\
+						 _flags),		\
+	}								\
+}
+#define CCU_GATE_NO_PARENT_DEFINE(_struct, _name,  _reg, _gate_mask,	\
+				  _val_enable, _val_disable, _flags)	\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 0,					\
+		.hw.init	= CCU_MIX_ORPHAN_INITHW(_name, _flags)	\
+	}								\
+}
+
+#define CCU_FACTOR_DEFINE(_struct, _name, _parent, _div, _mul)		\
+struct ccu_mix _struct = {						\
+	.factor	= CCU_FACTOR_INIT(_div, _mul),				\
+	.common = {							\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init	= CCU_MIX_INITHW(_name, _parent, 0),	\
+	}								\
+}
+
+#define CCU_MUX_DEFINE(_struct, _name, _parents, _reg, _shift, _width,	\
+		       _flags)						\
+struct ccu_mix _struct = {						\
+	.mux	= CCU_MUX_INIT(_shift, _width, NULL, 0),		\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.parent_names	= _parents,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	}								\
+}
+
+#define CCU_DIV_DEFINE(_struct, _name, _parent, _reg, _shift, _width,	\
+		       _flags)						\
+struct ccu_mix _struct = {						\
+	.div	= CCU_DIV_INIT(_shift, _width, NULL, 0),		\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init = CCU_MIX_INITHW(_name, _parent, _flags)	\
+	}								\
+}
+
+#define CCU_GATE_FACTOR_DEFINE(_struct, _name, _parent, _reg,		\
+			       _gate_mask, _val_enable, _val_disable,	\
+			       _div, _mul, _flags)			\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.factor	= CCU_FACTOR_INIT(_div, _mul),				\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init = CCU_MIX_INITHW(_name, _parent, _flags)	\
+	}								\
+}
+
+
+#define CCU_MUX_GATE_DEFINE(_struct, _name, _parents, _reg, _shift,	\
+			    _width, _gate_mask, _val_enable,		\
+			    _val_disable, _flags)			\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.mux	= CCU_MUX_INIT(_shift, _width, NULL, 0),		\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.parent_names	= _parents,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	}								\
+}
+
+#define CCU_DIV_GATE_DEFINE(_struct, _name, _parent, _reg, _shift,	\
+			    _width, _gate_mask, _val_enable,		\
+			    _val_disable, _flags)			\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_shift, _width, NULL, 0),		\
+	.common = {							\
+		.reg_ctrl	= _reg,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init	= CCU_MIX_INITHW(_name, _parent,	\
+						 _flags),		\
+	}								\
+}
+
+
+#define CCU_DIV_MUX_GATE_DEFINE(_struct, _name, _parents,  _reg_ctrl,	\
+				_mshift, _mwidth, _muxshift, _muxwidth,	\
+				_gate_mask, _val_enable, _val_disable,	\
+				_flags)					\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common	= {							\
+		.reg_ctrl	= _reg_ctrl,				\
+		.name		= _name,				\
+		.parent_names	= _parents,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+#define CCU_DIV2_FC_MUX_GATE_DEFINE(_struct, _name, _parents,		\
+				    _reg_ctrl, _reg_sel, _mshift,	\
+				    _mwidth, _fc, _muxshift, _muxwidth,	\
+				    _gate_mask, _val_enable,		\
+				    _val_disable, _flags)		\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+	    .reg_type = CLK_DIV_TYPE_2REG_FC_V4,			\
+		.reg_ctrl	= _reg_ctrl,				\
+		.reg_sel	= _reg_sel,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.parent_names	= _parents,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+
+#define CCU_DIV_FC_MUX_GATE_DEFINE(_struct, _name, _parents, _reg_ctrl,	\
+				   _mshift, _mwidth, _fc, _muxshift,	\
+				   _muxwidth, _gate_mask, _val_enable,	\
+				   _val_disable, _flags)		\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type	= CLK_DIV_TYPE_1REG_FC_V2,		\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.parent_names	= _parents,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+#define CCU_DIV_MFC_MUX_GATE_DEFINE(_struct, _name, _parents,		\
+				    _reg_ctrl, _mshift, _mwidth, _fc,	\
+				    _muxshift, _muxwidth, _gate_mask,	\
+				    _val_enable, _val_disable, _flags)	\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type = CLK_DIV_TYPE_1REG_FC_MUX_V6,		\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.parent_names	= _parents,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+		},							\
+	}								\
+}
+
+#define CCU_DIV_FC_WITH_GATE_DEFINE(_struct, _name, _parent, _reg_ctrl,	\
+				    _mshift, _mwidth, _fc, _gate_mask,	\
+				    _val_enable, _val_disable, _flags)	\
+struct ccu_mix _struct = {						\
+	.gate	= CCU_GATE_INIT(_gate_mask, _val_enable,		\
+				_val_disable, 0),			\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type = CLK_DIV_TYPE_1REG_FC_V2,			\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.num_parents	= 1,					\
+		.hw.init	= CCU_MIXINITHW(_name, _parent,		\
+						_flags),		\
+	},								\
+}
+
+#define CCU_DIV_FC_MUX_DEFINE(_struct, _name, _parents, _reg_ctrl,	\
+			      _mshift, _mwidth, _fc, _muxshift,		\
+			      _muxwidth, _flags)			\
+struct ccu_mix _struct = {						\
+	.div	= CCU_DIV_INIT(_mshift, _mwidth, NULL, 0),		\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type	= CLK_DIV_TYPE_1REG_FC_V2,		\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.parent_names	= _parents,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags),		\
+	},								\
+}
+
+#define CCU_MUX_FC_DEFINE(_struct, _name, _parents, _reg_ctrl, _fc,	\
+			  _muxshift, _muxwidth, _flags)			\
+struct ccu_mix _struct = {						\
+	.mux	= CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0),		\
+	.common = {							\
+		.reg_type	= CLK_DIV_TYPE_1REG_FC_V2,		\
+		.reg_ctrl	= _reg_ctrl,				\
+		.fc		= _fc,					\
+		.name		= _name,				\
+		.parent_names	= _parents,				\
+		.num_parents	= ARRAY_SIZE(_parents),			\
+		.hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents,	\
+						  _flags)		\
+	},								\
+}
+
+static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw)
+{
+	struct ccu_common *common = hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_mix, common);
+}
+
+extern const struct clk_ops spacemit_ccu_mix_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..2ab8d812d118
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_pll.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Spacemit clock type pll
+ *
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/regmap.h>
+
+#include "ccu_common.h"
+#include "ccu_pll.h"
+
+#define PLL_MIN_FREQ	600000000
+#define PLL_MAX_FREQ	3400000000
+#define PLL_DELAY_TIME	3000
+
+#define pll_read_swcr1(c, v)	ccu_read(ctrl, c, v)
+#define pll_read_swcr2(c, v)	ccu_read(sel, c, v)
+#define pll_read_swcr3(c, v)	ccu_read(xtc, c, v)
+
+#define pll_update_swcr1(c, m, v)	ccu_update(ctrl, c, m, v)
+#define pll_update_swcr2(c, m, v)	ccu_update(sel, c, m, v)
+#define pll_update_swcr3(c, m, v)	ccu_update(xtc, c, m, v)
+
+#define PLL_SWCR1_REG5_OFF	0
+#define PLL_SWCR1_REG5_MASK	GENMASK(7, 0)
+#define PLL_SWCR1_REG6_OFF	8
+#define PLL_SWCR1_REG6_MASK	GENMASK(15, 8)
+#define PLL_SWCR1_REG7_OFF	16
+#define PLL_SWCR1_REG7_MASK	GENMASK(23, 16)
+#define PLL_SWCR1_REG8_OFF	24
+#define PLL_SWCR1_REG8_MASK	GENMASK(31, 24)
+
+#define PLL_SWCR2_DIVn_EN(n)	BIT(n + 1)
+#define PLL_SWCR2_ATEST_EN	BIT(12)
+#define PLL_SWCR2_CKTEST_EN	BIT(13)
+#define PLL_SWCR2_DTEST_EN	BIT(14)
+
+#define PLL_SWCR3_DIV_FRC_OFF	0
+#define PLL_SWCR3_DIV_FRC_MASK	GENMASK(23, 0)
+#define PLL_SWCR3_DIV_INT_OFF	24
+#define PLL_SWCR3_DIV_INT_MASK	GENMASK(30, 24)
+#define PLL_SWCR3_EN		BIT(31)
+
+static int ccu_pll_is_enabled(struct clk_hw *hw)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	u32 tmp;
+
+	pll_read_swcr3(&p->common, &tmp);
+
+	return tmp & PLL_SWCR3_EN;
+}
+
+/* frequency unit Mhz, return pll vco freq */
+static unsigned long __get_vco_freq(struct clk_hw *hw)
+{
+	unsigned int reg5, reg6, reg7, reg8, size, i;
+	unsigned int div_int, div_frc;
+	struct ccu_pll_rate_tbl *freq_pll_regs_table;
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_common *common = &p->common;
+	u32 tmp;
+
+	pll_read_swcr1(common, &tmp);
+	reg5 = (tmp & PLL_SWCR1_REG5_MASK) >> PLL_SWCR1_REG5_OFF;
+	reg6 = (tmp & PLL_SWCR1_REG6_MASK) >> PLL_SWCR1_REG6_OFF;
+	reg7 = (tmp & PLL_SWCR1_REG7_MASK) >> PLL_SWCR1_REG7_OFF;
+	reg8 = (tmp & PLL_SWCR1_REG8_MASK) >> PLL_SWCR1_REG8_OFF;
+
+	pll_read_swcr3(common, &tmp);
+	div_int = (tmp & PLL_SWCR3_DIV_INT_MASK) >> PLL_SWCR3_DIV_INT_OFF;
+	div_frc = (tmp & PLL_SWCR3_DIV_FRC_MASK) >> PLL_SWCR3_DIV_FRC_OFF;
+
+	freq_pll_regs_table = p->pll.rate_tbl;
+	size = p->pll.tbl_size;
+
+	for (i = 0; i < size; i++)
+		if ((freq_pll_regs_table[i].reg5 == reg5) &&
+		    (freq_pll_regs_table[i].reg6 == reg6) &&
+		    (freq_pll_regs_table[i].reg7 == reg7) &&
+		    (freq_pll_regs_table[i].reg8 == reg8) &&
+		    (freq_pll_regs_table[i].div_int == div_int) &&
+		    (freq_pll_regs_table[i].div_frac == div_frc))
+			return freq_pll_regs_table[i].rate;
+
+	WARN_ON_ONCE(1);
+
+	return 0;
+}
+
+static int ccu_pll_enable(struct clk_hw *hw)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_common *common = &p->common;
+	unsigned long flags;
+	unsigned int tmp;
+	int ret;
+
+	if (ccu_pll_is_enabled(hw))
+		return 0;
+
+	spin_lock_irqsave(common->lock, flags);
+
+	pll_update_swcr3(common, PLL_SWCR3_EN, PLL_SWCR3_EN);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	/* check lock status */
+	ret = regmap_read_poll_timeout_atomic(common->lock_base,
+					      p->pll.reg_lock,
+					      tmp,
+					      tmp & p->pll.lock_enable_bit,
+					      5, PLL_DELAY_TIME);
+
+	return ret;
+}
+
+static void ccu_pll_disable(struct clk_hw *hw)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_common *common = &p->common;
+	unsigned long flags;
+
+	spin_lock_irqsave(p->common.lock, flags);
+
+	pll_update_swcr3(common, PLL_SWCR3_EN, 0);
+
+	spin_unlock_irqrestore(common->lock, flags);
+}
+
+/*
+ * pll rate change requires sequence:
+ * clock off -> change rate setting -> clock on
+ * This function doesn't really change rate, but cache the config
+ */
+static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long parent_rate)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_common *common = &p->common;
+	struct ccu_pll_config *params = &p->pll;
+	struct ccu_pll_rate_tbl *entry;
+	unsigned long old_rate;
+	unsigned long flags;
+	bool found = false;
+	u32 mask, val;
+	int i;
+
+	if (ccu_pll_is_enabled(hw)) {
+		pr_err("%s %s is enabled, ignore the setrate!\n",
+		       __func__, __clk_get_name(hw->clk));
+		return 0;
+	}
+
+	old_rate = __get_vco_freq(hw);
+
+	for (i = 0; i < params->tbl_size; i++) {
+		if (rate == params->rate_tbl[i].rate) {
+			found = true;
+			entry = &params->rate_tbl[i];
+			break;
+		}
+	}
+	WARN_ON_ONCE(!found);
+
+	spin_lock_irqsave(common->lock, flags);
+
+	mask = PLL_SWCR1_REG5_MASK | PLL_SWCR1_REG6_MASK;
+	mask |= PLL_SWCR1_REG7_MASK | PLL_SWCR1_REG8_MASK;
+	val |= entry->reg5 << PLL_SWCR1_REG5_OFF;
+	val |= entry->reg6 << PLL_SWCR1_REG6_OFF;
+	val |= entry->reg7 << PLL_SWCR1_REG7_OFF;
+	val |= entry->reg8 << PLL_SWCR1_REG8_OFF;
+	pll_update_swcr1(common, mask, val);
+
+	mask = PLL_SWCR3_DIV_INT_MASK | PLL_SWCR3_DIV_FRC_MASK;
+	val = entry->div_int << PLL_SWCR3_DIV_INT_OFF;
+	val |= entry->div_frac << PLL_SWCR3_DIV_FRC_OFF;
+	pll_update_swcr3(common, mask, val);
+
+	spin_unlock_irqrestore(common->lock, flags);
+
+	return 0;
+}
+
+static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	return __get_vco_freq(hw);
+}
+
+static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *prate)
+{
+	struct ccu_pll *p = hw_to_ccu_pll(hw);
+	struct ccu_pll_config *params = &p->pll;
+	unsigned long max_rate = 0;
+	unsigned int i;
+
+	if (rate > PLL_MAX_FREQ || rate < PLL_MIN_FREQ) {
+		pr_err("%lu rate out of range!\n", rate);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < params->tbl_size; i++) {
+		if (params->rate_tbl[i].rate <= rate) {
+			if (max_rate < params->rate_tbl[i].rate)
+				max_rate = params->rate_tbl[i].rate;
+		}
+	}
+
+	return max_rate;
+}
+
+const struct clk_ops spacemit_ccu_pll_ops = {
+	.enable = ccu_pll_enable,
+	.disable = ccu_pll_disable,
+	.set_rate = ccu_pll_set_rate,
+	.recalc_rate = ccu_pll_recalc_rate,
+	.round_rate = ccu_pll_round_rate,
+	.is_enabled = 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..c5dec2c0394b
--- /dev/null
+++ b/drivers/clk/spacemit/ccu_pll.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 SpacemiT Technology Co. Ltd
+ * Copyright (c) 2024 Haylen Chu <heylenay@outlook.com>
+ */
+
+#ifndef _CCU_PLL_H_
+#define _CCU_PLL_H_
+
+#include <linux/spinlock_types.h>
+#include <linux/clk-provider.h>
+#include "ccu_common.h"
+
+struct ccu_pll_rate_tbl {
+	unsigned long long rate;
+	u32 reg5;
+	u32 reg6;
+	u32 reg7;
+	u32 reg8;
+	unsigned int div_int;
+	unsigned int div_frac;
+};
+
+struct ccu_pll_config {
+	struct ccu_pll_rate_tbl *rate_tbl;
+	u32 tbl_size;
+	u32 reg_lock;
+	u32 lock_enable_bit;
+};
+
+#define CCU_PLL_RATE(_rate, _reg5, _reg6, _reg7, _reg8, _div_int, _div_frac) \
+	{									\
+		.rate		= (_rate),					\
+		.reg5		= (_reg5),					\
+		.reg6		= (_reg6),					\
+		.reg7		= (_reg7),					\
+		.reg8		= (_reg8),					\
+		.div_int	= (_div_int),				\
+		.div_frac	= (_div_frac),				\
+	}
+
+struct ccu_pll {
+	struct ccu_pll_config	pll;
+	struct ccu_common	common;
+};
+
+#define CCU_PLL_CONFIG(_table, _reg_lock, _lock_enable_bit) \
+	{									\
+		.rate_tbl	 = (struct ccu_pll_rate_tbl *)&(_table),	\
+		.tbl_size	 = ARRAY_SIZE(_table),				\
+		.reg_lock	 = (_reg_lock),					\
+		.lock_enable_bit = (_lock_enable_bit),				\
+	}
+
+#define CCU_PLL_HWINIT(_name, _flags) \
+	CLK_HW_INIT_NO_PARENT(_name, &spacemit_ccu_pll_ops, _flags)
+
+#define CCU_PLL_DEFINE(_struct, _name, _table, _reg_ctrl, _reg_sel,	\
+		       _reg_xtc, _reg_lock, _lock_enable_bit, _flags)		\
+										\
+	struct ccu_pll _struct = {						\
+		.pll	= CCU_PLL_CONFIG(_table, _reg_lock, _lock_enable_bit),	\
+		.common = {							\
+			.reg_ctrl	= _reg_ctrl,				\
+			.reg_sel	= _reg_sel,				\
+			.reg_xtc	= _reg_xtc,				\
+			.is_pll		= true,					\
+			.hw.init	= CCU_PLL_HWINIT(_name, _flags)		\
+		}								\
+	}
+
+
+static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw)
+{
+	struct ccu_common *common = hw_to_ccu_common(hw);
+
+	return container_of(common, struct ccu_pll, common);
+}
+
+extern const struct clk_ops spacemit_ccu_pll_ops;
+
+#endif
-- 
2.46.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC
  2024-08-31 15:47 ` [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC Haylen Chu
@ 2024-08-31 17:19   ` Rob Herring (Arm)
  2024-09-01 10:55   ` Krzysztof Kozlowski
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Rob Herring (Arm) @ 2024-08-31 17:19 UTC (permalink / raw)
  To: Haylen Chu
  Cc: Michael Turquette, linux-clk, devicetree, Stephen Boyd,
	Conor Dooley, Krzysztof Kozlowski, linux-kernel


On Sat, 31 Aug 2024 15:47:12 +0000, Haylen Chu wrote:
> Add definition for the clock controllers of Spacemit K1 SoC. The clock
> tree is managed by several SoC parts, thus different compatible strings
> are added for each.
> 
> Signed-off-by: Haylen Chu <heylenay@outlook.com>
> ---
>  .../bindings/clock/spacemit,ccu.yaml          | 116 +++++++++++
>  include/dt-bindings/clock/spacemit,ccu.h      | 197 ++++++++++++++++++
>  2 files changed, 313 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
>  create mode 100644 include/dt-bindings/clock/spacemit,ccu.h
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/clock/spacemit,ccu.example.dtb: system-control@d4090000: reg: [[0, 3557359616], [0, 4096]] is too long
	from schema $id: http://devicetree.org/schemas/mfd/syscon-common.yaml#
Documentation/devicetree/bindings/clock/spacemit,ccu.example.dtb: /example-0/system-control@d4090000: failed to match any schema with compatible: ['spacemit,mpmu-syscon', 'syscon', 'simple-mfd']
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/clock/spacemit,ccu.example.dtb: clock-controller: 'spacemit,mpmu' does not match any of the regexes: '^#.*', '^(at25|bm|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio-key|gpio|gpmc|hdmi|i2c-gpio),.*', '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', '^(pinctrl-single|#pinctrl-single|PowerPC),.*', '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^100ask,.*', '^70mai,.*', '^8dev,.*', '^GEFanuc,.*', '^IBM,.*', '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abb,.*', '^abilis,.*', '^abracon,.*', '^abt,.*', '^acbel,.*', '^acelink,.*', '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', '^adieng,.*', '^admatec,.*', '^advantech,.*', '^aeroflexgaisler,.*', '^aesop,.*', '^airoha,.*', '^al,.*', '^alcatel,.*', '^aldec,.*', '^alfa-network,.*', '^allegro,.*', '^alliedvision,.*', '^allo,.*', '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^alt,.*', '^altr,.*', '^amarula,.*', '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', '^ampere,.*', '^amphenol,.*', '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^anbernic,.*', '^andestech,.*', '^anvo,.*', '^aosong,.*', '^apm,.*', '^apple,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', '^arcom,.*', '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', '^armsom,.*', '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^asix,.*', '^aspeed,.*', '^asrock,.*', '^asteralabs,.*', '^asus,.*', '^atheros,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', '^beagle,.*', '^belling,.*', '^bhf,.*', '^bigtreetech,.*', '^bitmain,.*', '^blutek,.*', '^boe,.*', '^bosch,.*', '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bsh,.*', '^bticino,.*', '^buffalo,.*', '^bur,.*', '^bytedance,.*', '^calamp,.*', '^calao,.*', '^calaosystems,.*', '^calxeda,.*', '^cameo,.*', '^canaan,.*', '^caninos,.*', '^capella,.*', '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cct,.*', '^cdns,.*', '^cdtech,.*', '^cellwise,.*', '^ceva,.*', '^chargebyte,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', '^chipone,.*', '^chipspark,.*', '^chongzhou,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cisco,.*', '^clockwork,.*', '^cloos,.*', '^cloudengines,.*', '^cnm,.*', '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^congatec,.*', '^coolpi,.*', '^coreriver,.*', '^corpro,.*', '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', '^csky,.*', '^csq,.*', '^ctera,.*', '^ctu,.*', '^cubietech,.*', '^cudy,.*', '^cui,.*', '^cypress,.*', '^cyx,.*', '^cznic,.*', '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', '^densitron,.*', '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', '^digilent,.*', '^dimonoff,.*', '^diodes,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', '^domintech,.*', '^dongwoon,.*', '^dptechnics,.*', '^dragino,.*', '^dream,.*', '^ds,.*', '^dserve,.*', '^dynaimage,.*', '^ea,.*', '^ebang,.*', '^ebbg,.*', '^ebs-systart,.*', '^ebv,.*', '^eckelmann,.*', '^edgeble,.*', '^edimax,.*', '^edt,.*', '^ees,.*', '^eeti,.*', '^einfochips,.*', '^eink,.*', '^elan,.*', '^element14,.*', '^elgin,.*', '^elida,.*', '^elimo,.*', '^elpida,.*', '^embedfire,.*', '^embest,.*', '^emcraft,.*', '^emlid,.*', '^emmicro,.*', '^empire-electronix,.*', '^emtrion,.*', '^enclustra,.*', '^endless,.*', '^ene,.*', '^energymicro,.*', '^engicam,.*', '^engleder,.*', '^epcos,.*', '^epfl,.*', '^epson,.*', '^esp,.*', '^est,.*', '^ettus,.*', '^eukrea,.*', '^everest,.*', '^everspin,.*', '^evervision,.*', '^exar,.*', '^excito,.*', '^exegin,.*', '^ezchip,.*', '^facebook,.*', '^fairchild,.*', '^fairphone,.*', '^faraday,.*', '^fascontek,.*', '^fastrax,.*', '^fcs,.*', '^feixin,.*', '^feiyang,.*', '^fii,.*', '^firefly,.*', '^focaltech,.*', '^forlinx,.*', '^freebox,.*', '^freecom,.*', '^frida,.*', '^friendlyarm,.*', '^fsl,.*', '^fujitsu,.*', '^fxtec,.*', '^galaxycore,.*', '^gameforce,.*', '^gardena,.*', '^gateway,.*', '^gateworks,.*', '^gcw,.*', '^ge,.*', '^geekbuying,.*', '^gef,.*', '^gemei,.*', '^gemtek,.*', '^genesys,.*', '^geniatech,.*', '^giantec,.*', '^giantplus,.*', '^glinet,.*', '^globalscale,.*', '^globaltop,.*', '^gmt,.*', '^goldelico,.*', '^goodix,.*', '^google,.*', '^goramo,.*', '^gplus,.*', '^grinn,.*', '^grmn,.*', '^gumstix,.*', '^gw,.*', '^hannstar,.*', '^haochuangyi,.*', '^haoyu,.*', '^hardkernel,.*', '^hechuang,.*', '^hideep,.*', '^himax,.*', '^hirschmann,.*', '^hisi,.*', '^hisilicon,.*', '^hit,.*', '^hitex,.*', '^holt,.*', '^holtek,.*', '^honestar,.*', '^honeywell,.*', '^hoperf,.*', '^hoperun,.*', '^hp,.*', '^hpe,.*', '^hsg,.*', '^htc,.*', '^huawei,.*', '^hugsun,.*', '^hwacom,.*', '^hxt,.*', '^hycon,.*', '^hydis,.*', '^hynitron,.*', '^hynix,.*', '^hyundai,.*', '^i2se,.*', '^ibm,.*', '^icplus,.*', '^idt,.*', '^iei,.*', '^ifi,.*', '^ilitek,.*', '^imagis,.*', '^img,.*', '^imi,.*', '^inanbo,.*', '^incircuit,.*', '^indiedroid,.*', '^inet-tek,.*', '^infineon,.*', '^inforce,.*', '^ingenic,.*', '^ingrasys,.*', '^injoinic,.*', '^innocomm,.*', '^innolux,.*', '^inside-secure,.*', '^insignal,.*', '^inspur,.*', '^intel,.*', '^intercontrol,.*', '^invensense,.*', '^inventec,.*', '^inversepath,.*', '^iom,.*', '^irondevice,.*', '^isee,.*', '^isil,.*', '^issi,.*', '^ite,.*', '^itead,.*', '^itian,.*', '^ivo,.*', '^iwave,.*', '^jadard,.*', '^jasonic,.*', '^jdi,.*', '^jedec,.*', '^jesurun,.*', '^jethome,.*', '^jianda,.*', '^jide,.*', '^joz,.*', '^kam,.*', '^karo,.*', '^keithkoep,.*', '^keymile,.*', '^khadas,.*', '^kiebackpeter,.*', '^kinetic,.*', '^kingdisplay,.*', '^kingnovel,.*', '^kionix,.*', '^kobo,.*', '^kobol,.*', '^koe,.*', '^kontron,.*', '^kosagi,.*', '^kvg,.*', '^kyo,.*', '^lacie,.*', '^laird,.*', '^lamobo,.*', '^lantiq,.*', '^lattice,.*', '^lctech,.*', '^leadtek,.*', '^leez,.*', '^lego,.*', '^lemaker,.*', '^lenovo,.*', '^lg,.*', '^lgphilips,.*', '^libretech,.*', '^licheepi,.*', '^linaro,.*', '^lincolntech,.*', '^lineartechnology,.*', '^linksprite,.*', '^linksys,.*', '^linutronix,.*', '^linux,.*', '^linx,.*', '^liteon,.*', '^litex,.*', '^lltc,.*', '^logicpd,.*', '^logictechno,.*', '^longcheer,.*', '^lontium,.*', '^loongmasses,.*', '^loongson,.*', '^lsi,.*', '^lunzn,.*', '^luxul,.*', '^lwn,.*', '^lxa,.*', '^m5stack,.*', '^macnica,.*', '^mantix,.*', '^mapleboard,.*', '^marantec,.*', '^marvell,.*', '^maxbotix,.*', '^maxim,.*', '^maxlinear,.*', '^mbvl,.*', '^mcube,.*', '^meas,.*', '^mecer,.*', '^mediatek,.*', '^megachips,.*', '^mele,.*', '^melexis,.*', '^melfas,.*', '^mellanox,.*', '^memsensing,.*', '^memsic,.*', '^menlo,.*', '^mentor,.*', '^meraki,.*', '^merrii,.*', '^methode,.*', '^micrel,.*', '^microchip,.*', '^microcrystal,.*', '^micron,.*', '^microsoft,.*', '^microsys,.*', '^microtips,.*', '^mikroe,.*', '^mikrotik,.*', '^milkv,.*', '^miniand,.*', '^minix,.*', '^mips,.*', '^miramems,.*', '^mitsubishi,.*', '^mitsumi,.*', '^mixel,.*', '^miyoo,.*', '^mntre,.*', '^mobileye,.*', '^modtronix,.*', '^moortec,.*', '^mosaixtech,.*', '^motorcomm,.*', '^motorola,.*', '^moxa,.*', '^mpl,.*', '^mps,.*', '^mqmaker,.*', '^mrvl,.*', '^mscc,.*', '^msi,.*', '^mstar,.*', '^mti,.*', '^multi-inno,.*', '^mundoreader,.*', '^murata,.*', '^mxic,.*', '^mxicy,.*', '^myir,.*', '^national,.*', '^neardi,.*', '^nec,.*', '^neonode,.*', '^netgear,.*', '^netlogic,.*', '^netron-dy,.*', '^netronix,.*', '^netxeon,.*', '^neweast,.*', '^newhaven,.*', '^newvision,.*', '^nexbox,.*', '^nextthing,.*', '^ni,.*', '^nintendo,.*', '^nlt,.*', '^nokia,.*', '^nordic,.*', '^novatek,.*', '^novtech,.*', '^numonyx,.*', '^nutsboard,.*', '^nuvoton,.*', '^nvd,.*', '^nvidia,.*', '^nxp,.*', '^oceanic,.*', '^ocs,.*', '^oct,.*', '^okaya,.*', '^oki,.*', '^olimex,.*', '^olpc,.*', '^oneplus,.*', '^onie,.*', '^onion,.*', '^onnn,.*', '^ontat,.*', '^opalkelly,.*', '^openailab,.*', '^opencores,.*', '^openembed,.*', '^openpandora,.*', '^openrisc,.*', '^openwrt,.*', '^option,.*', '^oranth,.*', '^orisetech,.*', '^ortustech,.*', '^osddisplays,.*', '^osmc,.*', '^ouya,.*', '^overkiz,.*', '^ovti,.*', '^oxsemi,.*', '^ozzmaker,.*', '^panasonic,.*', '^parade,.*', '^parallax,.*', '^pda,.*', '^pericom,.*', '^pervasive,.*', '^phicomm,.*', '^phytec,.*', '^picochip,.*', '^pine64,.*', '^pineriver,.*', '^pixcir,.*', '^plantower,.*', '^plathome,.*', '^plda,.*', '^plx,.*', '^ply,.*', '^pni,.*', '^pocketbook,.*', '^polaroid,.*', '^polyhex,.*', '^portwell,.*', '^poslab,.*', '^pov,.*', '^powertip,.*', '^powervr,.*', '^powkiddy,.*', '^primeview,.*', '^primux,.*', '^probox2,.*', '^prt,.*', '^pulsedlight,.*', '^purism,.*', '^qca,.*', '^qcom,.*', '^qemu,.*', '^qi,.*', '^qiaodian,.*', '^qihua,.*', '^qishenglong,.*', '^qnap,.*', '^quanta,.*', '^radxa,.*', '^raidsonic,.*', '^ralink,.*', '^ramtron,.*', '^raspberrypi,.*', '^raydium,.*', '^rda,.*', '^realtek,.*', '^remarkable,.*', '^renesas,.*', '^rervision,.*', '^revotics,.*', '^rex,.*', '^richtek,.*', '^ricoh,.*', '^rikomagic,.*', '^riot,.*', '^riscv,.*', '^rockchip,.*', '^rocktech,.*', '^rohm,.*', '^ronbo,.*', '^roofull,.*', '^roseapplepi,.*', '^rve,.*', '^saef,.*', '^samsung,.*', '^samtec,.*', '^sancloud,.*', '^sandisk,.*', '^satoz,.*', '^sbs,.*', '^schindler,.*', '^schneider,.*', '^sciosense,.*', '^seagate,.*', '^seeed,.*', '^seirobotics,.*', '^semtech,.*', '^senseair,.*', '^sensirion,.*', '^sensortek,.*', '^sercomm,.*', '^sff,.*', '^sgd,.*', '^sgmicro,.*', '^sgx,.*', '^sharp,.*', '^shift,.*', '^shimafuji,.*', '^shineworld,.*', '^shiratech,.*', '^si-en,.*', '^si-linux,.*', '^siemens,.*', '^sifive,.*', '^sigma,.*', '^sii,.*', '^sil,.*', '^silabs,.*', '^silan,.*', '^silead,.*', '^silergy,.*', '^silex-insight,.*', '^siliconfile,.*', '^siliconmitus,.*', '^silvaco,.*', '^simtek,.*', '^sinlinx,.*', '^sinovoip,.*', '^sinowealth,.*', '^sipeed,.*', '^sirf,.*', '^sis,.*', '^sitronix,.*', '^skov,.*', '^skyworks,.*', '^smartlabs,.*', '^smartrg,.*', '^smi,.*', '^smsc,.*', '^snps,.*', '^sochip,.*', '^socionext,.*', '^solidrun,.*', '^solomon,.*', '^sony,.*', '^sophgo,.*', '^sourceparts,.*', '^spansion,.*', '^sparkfun,.*', '^spinalhdl,.*', '^sprd,.*', '^square,.*', '^ssi,.*', '^sst,.*', '^sstar,.*', '^st,.*', '^st-ericsson,.*', '^starfive,.*', '^starry,.*', '^startek,.*', '^starterkit,.*', '^ste,.*', '^stericsson,.*', '^storlink,.*', '^storm,.*', '^storopack,.*', '^summit,.*', '^sunchip,.*', '^sundance,.*', '^sunplus,.*', '^supermicro,.*', '^swir,.*', '^syna,.*', '^synology,.*', '^synopsys,.*', '^tbs,.*', '^tbs-biometrics,.*', '^tcg,.*', '^tcl,.*', '^tcs,.*', '^tdo,.*', '^team-source-display,.*', '^technexion,.*', '^technologic,.*', '^techstar,.*', '^techwell,.*', '^teejet,.*', '^teltonika,.*', '^tempo,.*', '^terasic,.*', '^tesla,.*', '^tfc,.*', '^thead,.*', '^thine,.*', '^thingyjp,.*', '^thundercomm,.*', '^thwc,.*', '^ti,.*', '^tianma,.*', '^tlm,.*', '^tmt,.*', '^topeet,.*', '^topic,.*', '^toppoly,.*', '^topwise,.*', '^toradex,.*', '^toshiba,.*', '^toumaz,.*', '^tpk,.*', '^tplink,.*', '^tpo,.*', '^tq,.*', '^transpeed,.*', '^traverse,.*', '^tronfy,.*', '^tronsmart,.*', '^truly,.*', '^tsd,.*', '^turing,.*', '^tyan,.*', '^u-blox,.*', '^u-boot,.*', '^ubnt,.*', '^ucrobotics,.*', '^udoo,.*', '^ufispace,.*', '^ugoos,.*', '^uni-t,.*', '^uniwest,.*', '^upisemi,.*', '^urt,.*', '^usi,.*', '^usr,.*', '^utoo,.*', '^v3,.*', '^vaisala,.*', '^vamrs,.*', '^variscite,.*', '^vdl,.*', '^vertexcom,.*', '^via,.*', '^vialab,.*', '^vicor,.*', '^videostrong,.*', '^virtio,.*', '^virtual,.*', '^vishay,.*', '^visionox,.*', '^vitesse,.*', '^vivante,.*', '^vivax,.*', '^vocore,.*', '^voipac,.*', '^voltafield,.*', '^vot,.*', '^vscom,.*', '^vxt,.*', '^wacom,.*', '^wanchanglong,.*', '^wand,.*', '^waveshare,.*', '^wd,.*', '^we,.*', '^welltech,.*', '^wetek,.*', '^wexler,.*', '^whwave,.*', '^wi2wi,.*', '^widora,.*', '^wiligear,.*', '^willsemi,.*', '^winbond,.*', '^wingtech,.*', '^winlink,.*', '^winstar,.*', '^wirelesstag,.*', '^wits,.*', '^wlf,.*', '^wm,.*', '^wobo,.*', '^wolfvision,.*', '^x-powers,.*', '^xen,.*', '^xes,.*', '^xiaomi,.*', '^xillybus,.*', '^xingbangda,.*', '^xinpeng,.*', '^xiphera,.*', '^xlnx,.*', '^xnano,.*', '^xunlong,.*', '^xylon,.*', '^yadro,.*', '^yamaha,.*', '^yes-optoelectronics,.*', '^yic,.*', '^yiming,.*', '^ylm,.*', '^yna,.*', '^yones-toptech,.*', '^ys,.*', '^ysoft,.*', '^zarlink,.*', '^zealz,.*', '^zeitec,.*', '^zidoo,.*', '^zii,.*', '^zinitix,.*', '^zkmagic,.*', '^zte,.*', '^zyxel,.*', 'pinctrl-[0-9]+'
	from schema $id: http://devicetree.org/schemas/vendor-prefixes.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/SEYPR01MB4221019943A7F5361957811FD7902@SEYPR01MB4221.apcprd01.prod.exchangelabs.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC
  2024-08-31 15:47 ` [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC Haylen Chu
  2024-08-31 17:19   ` Rob Herring (Arm)
@ 2024-09-01 10:55   ` Krzysztof Kozlowski
  2024-09-03  8:50     ` Haylen Chu
  2024-09-02  1:27   ` Inochi Amaoto
  2024-09-06  9:51   ` Chen Wang
  3 siblings, 1 reply; 9+ messages in thread
From: Krzysztof Kozlowski @ 2024-09-01 10:55 UTC (permalink / raw)
  To: Haylen Chu
  Cc: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-clk, devicetree,
	linux-kernel

On Sat, Aug 31, 2024 at 03:47:12PM +0000, Haylen Chu wrote:
> Add definition for the clock controllers of Spacemit K1 SoC. The clock
> tree is managed by several SoC parts, thus different compatible strings
> are added for each.
> 
> Signed-off-by: Haylen Chu <heylenay@outlook.com>
> ---

This wasn't ever tested...

>  .../bindings/clock/spacemit,ccu.yaml          | 116 +++++++++++
>  include/dt-bindings/clock/spacemit,ccu.h      | 197 ++++++++++++++++++
>  2 files changed, 313 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
>  create mode 100644 include/dt-bindings/clock/spacemit,ccu.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> new file mode 100644
> index 000000000000..90ddfc5e2a2f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> @@ -0,0 +1,116 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/spacemit,ccu.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Spacemit SoC Clock Controller

What's the SoC name?

> +
> +maintainers:
> +  - Haylen Chu <heylenay@outlook.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - spacemit,ccu-apbs
> +      - spacemit,ccu-mpmu
> +      - spacemit,ccu-apbc
> +      - spacemit,ccu-apmu
> +
> +  clocks: true

No, this must be specific. min/maxItems

> +
> +  clock-names: true

No, this must be specific. min/maxItems

> +
> +  spacemit,mpmu:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon managing "Main PMU (MPMU)" registers

Explain what for.


> +
> +  "#clock-cells":
> +    const: 1
> +    description:
> +      See <dt-bindings/clock/spacemit,ccu.h> for valid indices.
> +
> +required:
> +  - compatible
> +  - "#clock-cells"
> +
> +additionalProperties: false

This goes after allOf block.

> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: spacemit,ccu-apbs
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 1
> +
> +        clock-names:
> +          const: pll1_2457p6_vco

Don't use some weird, fake names. That's pll or vco or whatever the
input is called.

> +
> +      required:
> +        - compatible
> +        - clocks
> +        - clock-names
> +        - "#clock-cells"
> +        - spacemit,mpmu
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: spacemit,ccu-apbc
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 4
> +
> +        clock-names:
> +          items:
> +            - const: clk_32k
> +            - const: vctcxo_1
> +            - const: vctcxo_24
> +            - const: vctcxo_3
> +
> +      required:
> +        - compatible
> +        - clocks
> +        - clock-names
> +        - "#clock-cells"
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: spacemit,ccu-apmu
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 1
> +
> +        clock-names:
> +          const: vctcxo_24
> +
> +      required:
> +        - compatible
> +        - clocks
> +        - clock-names
> +        - "#clock-cells"
> +
> +examples:
> +  - |
> +    syscon_apbs: system-control@d4090000 {
> +        compatible = "spacemit,mpmu-syscon", "syscon",
> +        "simple-mfd";

Messed indentation.

Anyway, parent device nodes should have complete example.

> +        reg = <0x0 0xd4090000 0x0 0x1000>;
> +
> +        clk_apbs: clock-controller {
> +            compatible = "spacemit,ccu-apbs";
> +            clocks = <&pll1_2457p6_vco>;
> +            clock-names = "pll1_2457p6_vco";
> +            #clock-cells = <1>;
> +            spacemit,mpmu = <&syscon_mpmu>;
> +        };
> +    };
> diff --git a/include/dt-bindings/clock/spacemit,ccu.h b/include/dt-bindings/clock/spacemit,ccu.h
> new file mode 100644
> index 000000000000..ce84690684ff
> --- /dev/null
> +++ b/include/dt-bindings/clock/spacemit,ccu.h
> @@ -0,0 +1,197 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */

Use the same license. (one pointed out by checkpatch)

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC
  2024-08-31 15:47 ` [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC Haylen Chu
  2024-08-31 17:19   ` Rob Herring (Arm)
  2024-09-01 10:55   ` Krzysztof Kozlowski
@ 2024-09-02  1:27   ` Inochi Amaoto
  2024-09-06  9:51   ` Chen Wang
  3 siblings, 0 replies; 9+ messages in thread
From: Inochi Amaoto @ 2024-09-02  1:27 UTC (permalink / raw)
  To: Haylen Chu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-clk, devicetree, linux-kernel

On Sat, Aug 31, 2024 at 03:47:12PM GMT, Haylen Chu wrote:
> Add definition for the clock controllers of Spacemit K1 SoC. The clock
> tree is managed by several SoC parts, thus different compatible strings
> are added for each.
> 
> Signed-off-by: Haylen Chu <heylenay@outlook.com>
> ---
>  .../bindings/clock/spacemit,ccu.yaml          | 116 +++++++++++
>  include/dt-bindings/clock/spacemit,ccu.h      | 197 ++++++++++++++++++
>  2 files changed, 313 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
>  create mode 100644 include/dt-bindings/clock/spacemit,ccu.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> new file mode 100644
> index 000000000000..90ddfc5e2a2f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> @@ -0,0 +1,116 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/spacemit,ccu.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Spacemit SoC Clock Controller
> +
> +maintainers:
> +  - Haylen Chu <heylenay@outlook.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - spacemit,ccu-apbs
> +      - spacemit,ccu-mpmu
> +      - spacemit,ccu-apbc
> +      - spacemit,ccu-apmu
> +

Add K1 prefix.

> +  clocks: true
> +
> +  clock-names: true
> +
> +  spacemit,mpmu:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon managing "Main PMU (MPMU)" registers
> +
> +  "#clock-cells":
> +    const: 1
> +    description:
> +      See <dt-bindings/clock/spacemit,ccu.h> for valid indices.
> +
> +required:
> +  - compatible
> +  - "#clock-cells"
> +
> +additionalProperties: false
> +


> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: spacemit,ccu-apbs
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 1
> +
> +        clock-names:
> +          const: pll1_2457p6_vco
> +
> +      required:
> +        - compatible
> +        - clocks
> +        - clock-names
> +        - "#clock-cells"
> +        - spacemit,mpmu
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: spacemit,ccu-apbc
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 4
> +
> +        clock-names:
> +          items:
> +            - const: clk_32k
> +            - const: vctcxo_1
> +            - const: vctcxo_24
> +            - const: vctcxo_3
> +
> +      required:
> +        - compatible
> +        - clocks
> +        - clock-names
> +        - "#clock-cells"
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: spacemit,ccu-apmu
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 1
> +
> +        clock-names:
> +          const: vctcxo_24
> +
> +      required:
> +        - compatible
> +        - clocks
> +        - clock-names
> +        - "#clock-cells"
> +

Do not use this weird allOf, split this binding into multiple ones.
This also apply to the binding header if necessary.

> +examples:
> +  - |
> +    syscon_apbs: system-control@d4090000 {
> +        compatible = "spacemit,mpmu-syscon", "syscon",
> +        "simple-mfd";

syscon also needs binding.

> +        reg = <0x0 0xd4090000 0x0 0x1000>;
> +
> +        clk_apbs: clock-controller {
> +            compatible = "spacemit,ccu-apbs";
> +            clocks = <&pll1_2457p6_vco>;
> +            clock-names = "pll1_2457p6_vco";
> +            #clock-cells = <1>;
> +            spacemit,mpmu = <&syscon_mpmu>;
> +        };
> +    };
> diff --git a/include/dt-bindings/clock/spacemit,ccu.h b/include/dt-bindings/clock/spacemit,ccu.h
> new file mode 100644
> index 000000000000..ce84690684ff
> --- /dev/null
> +++ b/include/dt-bindings/clock/spacemit,ccu.h
> @@ -0,0 +1,197 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (C) 2024 Haylen Chu <heylenay@outlook.com>
> + */
> +
> +#ifndef _DT_BINDINGS_SPACEMIT_CCU_H_
> +#define _DT_BINDINGS_SPACEMIT_CCU_H_
> +
> +/*	APBS clocks	*/
> +#define CLK_PLL2		0
> +#define CLK_PLL3		1
> +#define CLK_PLL1_D2		2
> +#define CLK_PLL1_D3		3
> +#define CLK_PLL1_D4		4
> +#define CLK_PLL1_D5		5
> +#define CLK_PLL1_D6		6
> +#define CLK_PLL1_D7		7
> +#define CLK_PLL1_D8		8
> +#define CLK_PLL1_D11		9
> +#define CLK_PLL1_D13		10
> +#define CLK_PLL1_D23		11
> +#define CLK_PLL1_D64		12
> +#define CLK_PLL1_D10_AUD	13
> +#define CLK_PLL1_D100_AUD	14
> +#define CLK_PLL2_D1		15
> +#define CLK_PLL2_D2		16
> +#define CLK_PLL2_D3		17
> +#define CLK_PLL2_D4		18
> +#define CLK_PLL2_D5		19
> +#define CLK_PLL2_D6		20
> +#define CLK_PLL2_D7		21
> +#define CLK_PLL2_D8		22
> +#define CLK_PLL3_D1		23
> +#define CLK_PLL3_D2		24
> +#define CLK_PLL3_D3		25
> +#define CLK_PLL3_D4		26
> +#define CLK_PLL3_D5		27
> +#define CLK_PLL3_D6		28
> +#define CLK_PLL3_D7		29
> +#define CLK_PLL3_D8		30
> +#define CLK_PLL3_80		31
> +#define CLK_PLL3_40		32
> +#define CLK_PLL3_20		33
> +#define CLK_APBS_NUM		34
> +
> +/*	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_351		15
> +#define CLK_PLL1_409P6		16
> +#define CLK_PLL1_204P8		17
> +#define CLK_PLL1_491		18
> +#define CLK_PLL1_245P76		19
> +#define CLK_PLL1_614		20
> +#define CLK_PLL1_47P26		21
> +#define CLK_PLL1_31P5		22
> +#define CLK_PLL1_819		23
> +#define CLK_PLL1_1228		24
> +#define CLK_SLOW_UART		25
> +#define CLK_SLOW_UART1		26
> +#define CLK_SLOW_UART2		27
> +#define CLK_WDT			28
> +#define CLK_RIPC		29
> +#define CLK_I2S_SySCLK		30
> +#define CLK_I2S_BCLK		31
> +#define CLK_APB			32
> +#define CLK_MPMU_NUM		33
> +
> +/*	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_APBC_NUM		52
> +
> +/*	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		28
> +#define CLK_PCIE1		29
> +#define CLK_PCIE2		30
> +#define CLK_EMAC0_BUS		31
> +#define CLK_EMAC0_PTP		32
> +#define CLK_EMAC1_BUS		33
> +#define CLK_EMAC1_PTP		34
> +#define CLK_JPG			35
> +#define CLK_JPF_4KAFBC		36
> +#define CLK_JPF_2KAFBC		37
> +#define CLK_CCIC2PHY		38
> +#define CLK_CCIC3PHY		39
> +#define CLK_CSI			40
> +#define CLK_CAMM0		41
> +#define CLK_CAMM1		42
> +#define CLK_CAMM2		43
> +#define CLK_ISP_CPP		44
> +#define CLK_ISP_BUS		45
> +#define CLK_ISP			46
> +#define CLK_DPU_MCL		47
> +#define CLK_DPU_ESC		48
> +#define CLK_DPU_BIT		49
> +#define CLK_DPU_PXCLK		50
> +#define CLK_DPU_HCLK		51
> +#define CLK_DPU_SPI		52
> +#define CLK_DPU_SPI_HBUS	53
> +#define CLK_DPU_SPIBUS		54
> +#define CLK_DPU_SPI_ACLK	55
> +#define CLK_V2D			56
> +#define CLK_APMU_NUM		57
> +
> +#endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */
> -- 
> 2.46.0
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC
  2024-09-01 10:55   ` Krzysztof Kozlowski
@ 2024-09-03  8:50     ` Haylen Chu
  0 siblings, 0 replies; 9+ messages in thread
From: Haylen Chu @ 2024-09-03  8:50 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, linux-clk, devicetree,
	linux-kernel

On Sun, Sep 01, 2024 at 12:55:21PM +0200, Krzysztof Kozlowski wrote:
> On Sat, Aug 31, 2024 at 03:47:12PM +0000, Haylen Chu wrote:
> > Add definition for the clock controllers of Spacemit K1 SoC. The clock
> > tree is managed by several SoC parts, thus different compatible strings
> > are added for each.
> > 
> > Signed-off-by: Haylen Chu <heylenay@outlook.com>
> > ---
> 
> This wasn't ever tested...
> 
> >  .../bindings/clock/spacemit,ccu.yaml          | 116 +++++++++++
> >  include/dt-bindings/clock/spacemit,ccu.h      | 197 ++++++++++++++++++
> >  2 files changed, 313 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> >  create mode 100644 include/dt-bindings/clock/spacemit,ccu.h
> > 
> > diff --git a/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> > new file mode 100644
> > index 000000000000..90ddfc5e2a2f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> > @@ -0,0 +1,116 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/clock/spacemit,ccu.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Spacemit SoC Clock Controller
> 
> What's the SoC name?
> 
> > +
> > +maintainers:
> > +  - Haylen Chu <heylenay@outlook.com>
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - spacemit,ccu-apbs
> > +      - spacemit,ccu-mpmu
> > +      - spacemit,ccu-apbc
> > +      - spacemit,ccu-apmu
> > +
> > +  clocks: true
> 
> No, this must be specific. min/maxItems
> 
> > +
> > +  clock-names: true
> 
> No, this must be specific. min/maxItems
> 
> > +
> > +  spacemit,mpmu:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description:
> > +      Phandle to the syscon managing "Main PMU (MPMU)" registers
> 
> Explain what for.
> 
> > +
> > +  "#clock-cells":
> > +    const: 1
> > +    description:
> > +      See <dt-bindings/clock/spacemit,ccu.h> for valid indices.
> > +
> > +required:
> > +  - compatible
> > +  - "#clock-cells"
> > +
> > +additionalProperties: false
> 
> This goes after allOf block.
> 
> > +
> > +allOf:
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: spacemit,ccu-apbs
> > +    then:
> > +      properties:
> > +        clocks:
> > +          maxItems: 1
> > +
> > +        clock-names:
> > +          const: pll1_2457p6_vco
> 
> Don't use some weird, fake names. That's pll or vco or whatever the
> input is called.
> 
> > +
> > +      required:
> > +        - compatible
> > +        - clocks
> > +        - clock-names
> > +        - "#clock-cells"
> > +        - spacemit,mpmu
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: spacemit,ccu-apbc
> > +    then:
> > +      properties:
> > +        clocks:
> > +          maxItems: 4
> > +
> > +        clock-names:
> > +          items:
> > +            - const: clk_32k
> > +            - const: vctcxo_1
> > +            - const: vctcxo_24
> > +            - const: vctcxo_3
> > +
> > +      required:
> > +        - compatible
> > +        - clocks
> > +        - clock-names
> > +        - "#clock-cells"
> > +
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: spacemit,ccu-apmu
> > +    then:
> > +      properties:
> > +        clocks:
> > +          maxItems: 1
> > +
> > +        clock-names:
> > +          const: vctcxo_24
> > +
> > +      required:
> > +        - compatible
> > +        - clocks
> > +        - clock-names
> > +        - "#clock-cells"
> > +
> > +examples:
> > +  - |
> > +    syscon_apbs: system-control@d4090000 {
> > +        compatible = "spacemit,mpmu-syscon", "syscon",
> > +        "simple-mfd";
> 
> Messed indentation.
> 
> Anyway, parent device nodes should have complete example.
> 
> > +        reg = <0x0 0xd4090000 0x0 0x1000>;
> > +
> > +        clk_apbs: clock-controller {
> > +            compatible = "spacemit,ccu-apbs";
> > +            clocks = <&pll1_2457p6_vco>;
> > +            clock-names = "pll1_2457p6_vco";
> > +            #clock-cells = <1>;
> > +            spacemit,mpmu = <&syscon_mpmu>;
> > +        };
> > +    };
> > diff --git a/include/dt-bindings/clock/spacemit,ccu.h b/include/dt-bindings/clock/spacemit,ccu.h
> > new file mode 100644
> > index 000000000000..ce84690684ff
> > --- /dev/null
> > +++ b/include/dt-bindings/clock/spacemit,ccu.h
> > @@ -0,0 +1,197 @@
> > +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> 
> Use the same license. (one pointed out by checkpatch)
> 
> Best regards,
> Krzysztof
> 

Thansk for your time and review, I realized it is better to split out
multiple bindings instead of writing these messy "allOf" block. Will
also adapt your suggestions in v2.

Best regards,
Haylen Chu

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC
  2024-08-31 15:47 ` [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC Haylen Chu
                     ` (2 preceding siblings ...)
  2024-09-02  1:27   ` Inochi Amaoto
@ 2024-09-06  9:51   ` Chen Wang
  2024-09-16  9:00     ` Haylen Chu
  3 siblings, 1 reply; 9+ messages in thread
From: Chen Wang @ 2024-09-06  9:51 UTC (permalink / raw)
  To: Haylen Chu, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-clk, devicetree, linux-kernel


On 2024/8/31 23:47, Haylen Chu wrote:
> Add definition for the clock controllers of Spacemit K1 SoC. The clock
> tree is managed by several SoC parts, thus different compatible strings
> are added for each.
>
> Signed-off-by: Haylen Chu <heylenay@outlook.com>
> ---
>   .../bindings/clock/spacemit,ccu.yaml          | 116 +++++++++++
>   include/dt-bindings/clock/spacemit,ccu.h      | 197 ++++++++++++++++++
>   2 files changed, 313 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
>   create mode 100644 include/dt-bindings/clock/spacemit,ccu.h

Suggest to use format: <vendor name>,<soc name>-<clk name>, look at the 
files under Documentation/devicetree/bindings/clock

For example:

starfive,jh7110-pll

For your case:

spacemit,k1-xxx

BTW, What's "CCU"?

> diff --git a/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> new file mode 100644
> index 000000000000..90ddfc5e2a2f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> @@ -0,0 +1,116 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/spacemit,ccu.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Spacemit SoC Clock Controller
> +
> +maintainers:
> +  - Haylen Chu <heylenay@outlook.com>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - spacemit,ccu-apbs
> +      - spacemit,ccu-mpmu
> +      - spacemit,ccu-apbc
> +      - spacemit,ccu-apmu

Same as filename, compatible string should contain soc codename to 
differ from other soc of spacemit.

[......]



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC
  2024-09-06  9:51   ` Chen Wang
@ 2024-09-16  9:00     ` Haylen Chu
  0 siblings, 0 replies; 9+ messages in thread
From: Haylen Chu @ 2024-09-16  9:00 UTC (permalink / raw)
  To: Chen Wang, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-clk, devicetree, linux-kernel

On Fri, Sep 06, 2024 at 05:51:44PM +0800, Chen Wang wrote:
> 
> On 2024/8/31 23:47, Haylen Chu wrote:
> > Add definition for the clock controllers of Spacemit K1 SoC. The clock
> > tree is managed by several SoC parts, thus different compatible strings
> > are added for each.
> > 
> > Signed-off-by: Haylen Chu <heylenay@outlook.com>
> > ---
> >   .../bindings/clock/spacemit,ccu.yaml          | 116 +++++++++++
> >   include/dt-bindings/clock/spacemit,ccu.h      | 197 ++++++++++++++++++
> >   2 files changed, 313 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> >   create mode 100644 include/dt-bindings/clock/spacemit,ccu.h
> 
> Suggest to use format: <vendor name>,<soc name>-<clk name>, look at the
> files under Documentation/devicetree/bindings/clock
> 
> For example:
> 
> starfive,jh7110-pll
> 
> For your case:
> 
> spacemit,k1-xxx

Thanks for your advice.

> BTW, What's "CCU"?

The name is taken from vendor code and I think it should be "clock
control unit".

> > diff --git a/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> > new file mode 100644
> > index 000000000000..90ddfc5e2a2f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/spacemit,ccu.yaml
> > @@ -0,0 +1,116 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/clock/spacemit,ccu.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Spacemit SoC Clock Controller
> > +
> > +maintainers:
> > +  - Haylen Chu <heylenay@outlook.com>
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - spacemit,ccu-apbs
> > +      - spacemit,ccu-mpmu
> > +      - spacemit,ccu-apbc
> > +      - spacemit,ccu-apmu
> 
> Same as filename, compatible string should contain soc codename to differ
> from other soc of spacemit.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-09-16  9:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-31 15:45 [PATCH 0/2] Add clock controller support for Spacemit K1 Haylen Chu
2024-08-31 15:47 ` [PATCH 1/2] dt-bindings: clock: spacemit: Add clock controlers of Spacemit K1 SoC Haylen Chu
2024-08-31 17:19   ` Rob Herring (Arm)
2024-09-01 10:55   ` Krzysztof Kozlowski
2024-09-03  8:50     ` Haylen Chu
2024-09-02  1:27   ` Inochi Amaoto
2024-09-06  9:51   ` Chen Wang
2024-09-16  9:00     ` Haylen Chu
2024-08-31 15:47 ` [PATCH 2/2] clk: spacemit: Add clock support for " Haylen Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®