All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] clk: samsung: Introduce Exynos5515 clock driver support
@ 2026-08-17 10:17 ` Aiden Isik
  0 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik via B4 Relay @ 2026-08-17 10:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
	Brian Masney, Rob Herring, Conor Dooley, Kees Cook,
	Gustavo A. R. Silva
  Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, linux-hardening, Aiden Isik

Hi there,

This patchset introduces clock driver support for the Exynos5515 SoC.

Currently, the following CMU blocks are defined:
- CMU_TOP (handles clocks for all child CMU blocks)
- CMU_PERI (handles clocks for USI, watchdog timer, etc)
- CMU_FSYS (handles clocks for MMC, USB, etc)

This driver support makes use of HWACG (hardware automatic clock gating),
so gates do not need to be manually forced on with CLK_IGNORE_UNUSED or
CLK_IS_CRITICAL. Rather, the hardware handles the clock gating.

Support for more blocks to come as support for the the hardware requiring
them is added.

I am getting some checkpatch warnings telling me to check the MAINTAINERS
file, as new files have been added. I am assuming these can be ignored as
I am not a maintainer, and the whole clock driver and samsung subsystems
already have maintainers listed.

Kind regards,
- Aiden Isik

Signed-off-by: Aiden Isik <aidenisik+git@member.fsf.org>
---
Aiden Isik (3):
      dt-bindings: clock: Add Exynos5515 SoC
      clk: samsung: clk-pll: Add support for pll_309
      clk: samsung: Introduce Exynos5515 clock driver

 .../bindings/clock/samsung,exynos5515-cmu.yaml     |  145 ++
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-exynos5515.c               | 1485 ++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c                      |   57 +-
 drivers/clk/samsung/clk-pll.h                      |    1 +
 include/dt-bindings/clock/samsung,exynos5515-cmu.h |  191 +++
 6 files changed, 1854 insertions(+), 26 deletions(-)
---
base-commit: acde40ba506aae78633e080b5704d33cf4bc13c6
change-id: 20260815-for-next-lucky7-clock-3b4b7e6b1ce4

Best regards,
--  
Aiden Isik <aidenisik@member.fsf.org>



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

* [PATCH 0/3] clk: samsung: Introduce Exynos5515 clock driver support
@ 2026-08-17 10:17 ` Aiden Isik
  0 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik @ 2026-08-17 10:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
	Brian Masney, Rob Herring, Conor Dooley, Kees Cook,
	Gustavo A. R. Silva
  Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, linux-hardening, Aiden Isik

Hi there,

This patchset introduces clock driver support for the Exynos5515 SoC.

Currently, the following CMU blocks are defined:
- CMU_TOP (handles clocks for all child CMU blocks)
- CMU_PERI (handles clocks for USI, watchdog timer, etc)
- CMU_FSYS (handles clocks for MMC, USB, etc)

This driver support makes use of HWACG (hardware automatic clock gating),
so gates do not need to be manually forced on with CLK_IGNORE_UNUSED or
CLK_IS_CRITICAL. Rather, the hardware handles the clock gating.

Support for more blocks to come as support for the the hardware requiring
them is added.

I am getting some checkpatch warnings telling me to check the MAINTAINERS
file, as new files have been added. I am assuming these can be ignored as
I am not a maintainer, and the whole clock driver and samsung subsystems
already have maintainers listed.

Kind regards,
- Aiden Isik

Signed-off-by: Aiden Isik <aidenisik+git@member.fsf.org>
---
Aiden Isik (3):
      dt-bindings: clock: Add Exynos5515 SoC
      clk: samsung: clk-pll: Add support for pll_309
      clk: samsung: Introduce Exynos5515 clock driver

 .../bindings/clock/samsung,exynos5515-cmu.yaml     |  145 ++
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-exynos5515.c               | 1485 ++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c                      |   57 +-
 drivers/clk/samsung/clk-pll.h                      |    1 +
 include/dt-bindings/clock/samsung,exynos5515-cmu.h |  191 +++
 6 files changed, 1854 insertions(+), 26 deletions(-)
---
base-commit: acde40ba506aae78633e080b5704d33cf4bc13c6
change-id: 20260815-for-next-lucky7-clock-3b4b7e6b1ce4

Best regards,
--  
Aiden Isik <aidenisik@member.fsf.org>


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

* [PATCH 1/3] dt-bindings: clock: Add Exynos5515 SoC
  2026-08-17 10:17 ` Aiden Isik
@ 2026-08-17 10:17   ` Aiden Isik
  -1 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik via B4 Relay @ 2026-08-17 10:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
	Brian Masney, Rob Herring, Conor Dooley, Kees Cook,
	Gustavo A. R. Silva
  Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, linux-hardening, Aiden Isik

From: Aiden Isik <aidenisik@member.fsf.org>

Add devicetree documentation for the Exynos5515 SoC's CMUs.

Add device tree bindings for the following CMUs:
- CMU_TOP
- CMU_PERI
- CMU_FSYS

Signed-off-by: Aiden Isik <aidenisik+git@member.fsf.org>
---
 .../bindings/clock/samsung,exynos5515-cmu.yaml     | 145 ++++++++++++++++
 include/dt-bindings/clock/samsung,exynos5515-cmu.h | 191 +++++++++++++++++++++
 2 files changed, 336 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml
new file mode 100644
index 000000000000..1be8962cda1c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml
@@ -0,0 +1,145 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos5515-cmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos5515 SoC clock controller
+
+maintainers:
+  - Aiden Isik <aidenisik+git@member.fsf.org>
+  - Chanwoo Choi <cw00.choi@samsung.com>
+  - Krzysztof Kozlowski <krzk@kernel.org>
+
+description: |
+  Exynos5515 clock controller is comprised of several CMU units, generating
+  clocks for different domains. Those CMU units are modeled as separate device
+  tree nodes, and might depend on each other. The root clock in that root tree
+  is an external clock: OSCCLK (26 MHz). This external clock must be defined
+  as a fixed-rate clock in dts.
+
+  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
+  dividers; all other clocks of function blocks (other CMUs) are usually
+  derived from CMU_TOP.
+
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All clocks available for usage
+  in clock consumer nodes are defined as preprocessor macros in
+  'include/dt-bindings/clock/samsung,exynos5515-cmu.h' header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos5515-cmu-fsys
+      - samsung,exynos5515-cmu-peri
+      - samsung,exynos5515-cmu-top
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  samsung,sysreg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to system registers interface.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+  - samsung,sysreg
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos5515-cmu-fsys
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26MHz)
+            - description: CMU_FSYS BUS clock (from CMU_TOP)
+            - description: CMU_FSYS MMC card clock (from CMU_TOP)
+            - description: CMU_FSYS MMC embedded clock (from CMU_TOP)
+            - description: CMU_FSYS USB20DRD clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: bus
+            - const: mmc_card
+            - const: mmc_embd
+            - const: usb20drd
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos5515-cmu-peri
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26MHz)
+            - description: CMU_PERI BUS clock (from CMU_TOP)
+            - description: CMU_PERI IP clock (from CMU_TOP)
+            - description: CMU_PERI UART clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: bus
+            - const: ip
+            - const: uart
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5515-cmu-top
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+
+        clock-names:
+          items:
+            - const: oscclk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/samsung,exynos5515-cmu.h>
+
+    cmu_top: clock-controller@15410000 {
+        compatible = "samsung,exynos5515-cmu-top";
+        reg = <0x15410000 0x10000>;
+        #clock-cells = <1>;
+
+        clocks = <&oscclk>;
+        clock-names = "oscclk";
+        samsung,sysreg = <&sysreg_top>;
+    };
+
+...
diff --git a/include/dt-bindings/clock/samsung,exynos5515-cmu.h b/include/dt-bindings/clock/samsung,exynos5515-cmu.h
new file mode 100644
index 000000000000..2877d3681b55
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,exynos5515-cmu.h
@@ -0,0 +1,191 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2026 Aiden Isik <aidenisik+git@member.fsf.org>
+ * Author: Aiden Isik <aidenisik+git@member.fsf.org>
+ *
+ * Device Tree binding constants for Exynos5515 clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS5515_H
+#define _DT_BINDINGS_CLOCK_EXYNOS5515_H
+
+/* CMU_TOP */
+#define CLK_FOUT_AUD_PLL			1
+#define CLK_FOUT_SHARED0_PLL			2
+#define CLK_FOUT_SHARED1_PLL			3
+
+#define CLK_MOUT_CMU_APM_BUS			4
+#define CLK_MOUT_CMU_CORE_BUS			5
+#define CLK_MOUT_CMU_CORE_SSS			6
+#define CLK_MOUT_CMU_CPUCL0_BUSP		7
+#define CLK_MOUT_CMU_CPUCL0_CPU			8
+#define CLK_MOUT_CMU_CPUCL0_DBG			9
+#define CLK_MOUT_CMU_DPU_AUDIF			10
+#define CLK_MOUT_CMU_DPU_AUD_BUS		11
+#define CLK_MOUT_CMU_DPU_AUD_CPU		12
+#define CLK_MOUT_CMU_DPU_BUS			13
+#define CLK_MOUT_CMU_FSYS_BUS			14
+#define CLK_MOUT_CMU_FSYS_MMC_CARD		15
+#define CLK_MOUT_CMU_FSYS_MMC_EMBD		16
+#define CLK_MOUT_CMU_FSYS_USB20DRD		17
+#define CLK_MOUT_CMU_G3D_BUS			18
+#define CLK_MOUT_CMU_MFC_BUS			19
+#define CLK_MOUT_CMU_MIF_BUSP			20
+#define CLK_MOUT_CMU_MIF_SWITCH			21
+#define CLK_MOUT_CMU_MODEM_SHARED1		22
+#define CLK_MOUT_CMU_PERI_BUS			23
+#define CLK_MOUT_CMU_PERI_IP			24
+#define CLK_MOUT_CMU_PERI_UART			25
+#define CLK_MOUT_CMU_CMUREF			26
+
+#define CLK_DOUT_AP2CP_SHARED0_PLL		27
+#define CLK_DOUT_AP2CP_SHARED1_PLL		28
+#define CLK_DOUT_AP2CP_SHARED2_PLL		29
+#define CLK_DOUT_CMU_APM_BUS			30
+#define CLK_DOUT_CMU_CMU_BOOST			31
+#define CLK_DOUT_CMU_CORE_BUS			32
+#define CLK_DOUT_CMU_CORE_SSS			33
+#define CLK_DOUT_CMU_CPUCL0_BUSP		34
+#define CLK_DOUT_CMU_CPUCL0_CPU			35
+#define CLK_DOUT_CMU_CPUCL0_DBG			36
+#define CLK_DOUT_CMU_DPU_AUDIF			37
+#define CLK_DOUT_CMU_DPU_AUD_BUS		38
+#define CLK_DOUT_CMU_DPU_AUD_CPU		39
+#define CLK_DOUT_CMU_DPU_BUS			40
+#define CLK_DOUT_CMU_FSYS_BUS			41
+#define CLK_DOUT_CMU_FSYS_MMC_CARD		42
+#define CLK_DOUT_CMU_FSYS_MMC_EMBD		43
+#define CLK_DOUT_CMU_FSYS_USB20DRD		44
+#define CLK_DOUT_CMU_G3D_BUS			45
+#define CLK_DOUT_CMU_MFC_BUS			46
+#define CLK_DOUT_CMU_MIF_BUSP			47
+#define CLK_DOUT_CMU_PERI_BUS			48
+#define CLK_DOUT_CMU_PERI_IP			49
+#define CLK_DOUT_CMU_PERI_UART			50
+#define CLK_DOUT_CMU_CMUREF			51
+
+#define CLK_DOUT_SHARED0_DIV2			52
+#define CLK_DOUT_SHARED0_DIV3			53
+#define CLK_DOUT_SHARED0_DIV4			54
+#define CLK_DOUT_SHARED1_DIV2			55
+#define CLK_DOUT_SHARED1_DIV3			56
+#define CLK_DOUT_SHARED1_DIV4			57
+#define CLK_DOUT_AUD_DIV2			58
+#define CLK_DOUT_AUD_DIV3			59
+#define CLK_DOUT_AUD_DIV4			60
+
+#define CLK_GOUT_CMU_MIF_SWITCH			61
+#define CLK_GOUT_CMU_APM_BUS			62
+#define CLK_GOUT_CMU_CORE_BUS			63
+#define CLK_GOUT_CMU_CORE_SSS			64
+#define CLK_GOUT_CMU_CPUCL0_BUSP		65
+#define CLK_GOUT_CMU_CPUCL0_CPU			66
+#define CLK_GOUT_CMU_CPUCL0_DBG			67
+#define CLK_GOUT_CMU_DPU_AUDIF			68
+#define CLK_GOUT_CMU_DPU_AUD_BUS		69
+#define CLK_GOUT_CMU_DPU_AUD_CPU		70
+#define CLK_GOUT_CMU_DPU_BUS			71
+#define CLK_GOUT_CMU_FSYS_BUS			72
+#define CLK_GOUT_CMU_FSYS_MMC_CARD		73
+#define CLK_GOUT_CMU_FSYS_MMC_EMBD		74
+#define CLK_GOUT_CMU_FSYS_USB20DRD		75
+#define CLK_GOUT_CMU_G3D_BUS			76
+#define CLK_GOUT_CMU_MFC_BUS			77
+#define CLK_GOUT_CMU_MIF_BUSP			78
+#define CLK_GOUT_CMU_MODEM_SHARED0		79
+#define CLK_GOUT_CMU_MODEM_SHARED1		80
+#define CLK_GOUT_CMU_MODEM_SHARED2		81
+#define CLK_GOUT_CMU_PERI_BUS			82
+#define CLK_GOUT_CMU_PERI_IP			83
+#define CLK_GOUT_CMU_PERI_UART			84
+
+/* CMU_PERI */
+#define CLK_MOUT_PLL_PERI_BUS_USER		1
+#define CLK_MOUT_PLL_PERI_IP_USER		2
+#define CLK_MOUT_PLL_PERI_UART_USER		3
+#define CLK_MOUT_PERI_SPI			4
+#define CLK_MOUT_PERI_USI00_USI			5
+
+#define CLK_DOUT_PERI_OTP			6
+
+#define CLK_DOUT_PERI_I2C_0			7
+#define CLK_DOUT_PERI_I2C_1			8
+#define CLK_DOUT_PERI_I2C_2			9
+#define CLK_DOUT_PERI_I2C_3			10
+#define CLK_DOUT_PERI_SPI			11
+#define CLK_DOUT_PERI_USI00_I2C			12
+#define CLK_DOUT_PERI_USI00_USI			13
+
+#define CLK_GOUT_PERI_BUSIF_TMU_PCLK		14
+#define CLK_GOUT_PERI_D_TZPC_PCLK		15
+#define CLK_GOUT_PERI_GPIO_PCLK			16
+#define CLK_GOUT_PERI_I2C_0_IPCLK		17
+#define CLK_GOUT_PERI_I2C_0_PCLK		18
+#define CLK_GOUT_PERI_I2C_1_IPCLK		19
+#define CLK_GOUT_PERI_I2C_1_PCLK		20
+#define CLK_GOUT_PERI_I2C_2_IPCLK		21
+#define CLK_GOUT_PERI_I2C_2_PCLK		22
+#define CLK_GOUT_PERI_I2C_3_IPCLK		23
+#define CLK_GOUT_PERI_I2C_3_PCLK		24
+#define CLK_GOUT_PERI_MCT_PCLK			25
+#define CLK_GOUT_PERI_OTP_OSCCLK		26
+#define CLK_GOUT_PERI_OTP_PCLK			27
+#define CLK_GOUT_PERI_CMU_PCLK			28
+#define CLK_GOUT_PERI_PWM_MOTOR_PCLK		29
+#define CLK_GOUT_PERI_BUS_CLK			30
+#define CLK_GOUT_PERI_I2C_0_CLK			31
+#define CLK_GOUT_PERI_I2C_1_CLK			32
+#define CLK_GOUT_PERI_I2C_2_CLK			33
+#define CLK_GOUT_PERI_I2C_3_CLK			34
+#define CLK_GOUT_PERI_OSCCLK			35
+#define CLK_GOUT_PERI_SPI_CLK			36
+#define CLK_GOUT_PERI_UART_CLK			37
+#define CLK_GOUT_PERI_USI00_I2C_CLK		38
+#define CLK_GOUT_PERI_USI00_USI_CLK		39
+#define CLK_GOUT_PERI_SLH_AXI_MI_P_CLK		40
+#define CLK_GOUT_PERI_SYSREG_PCLK		41
+#define CLK_GOUT_PERI_USI00_I2C_IPCLK		42
+#define CLK_GOUT_PERI_USI00_I2C_PCLK		43
+#define CLK_GOUT_PERI_USI00_USI_IPCLK		44
+#define CLK_GOUT_PERI_USI00_USI_PCLK		45
+#define CLK_GOUT_PERI_USI_SPI_IPCLK		46
+#define CLK_GOUT_PERI_USI_SPI_PCLK		47
+#define CLK_GOUT_PERI_USI_UART_IPCLK		48
+#define CLK_GOUT_PERI_USI_UART_PCLK		49
+#define CLK_GOUT_PERI_WDT0_PCLK			50
+#define CLK_GOUT_PERI_WDT1_PCLK			51
+#define CLK_GOUT_PERI_I2C_0			52
+#define CLK_GOUT_PERI_I2C_1			53
+#define CLK_GOUT_PERI_I2C_2			54
+#define CLK_GOUT_PERI_I2C_3			55
+#define CLK_GOUT_PERI_USI00_I2C			56
+
+/* CMU_FSYS */
+#define CLK_MOUT_PLL_FSYS_BUS_USER		1
+#define CLK_MOUT_PLL_FSYS_MMC_CARD_USER		2
+#define CLK_MOUT_PLL_FSYS_MMC_EMBD_USER		3
+#define CLK_MOUT_PLL_FSYS_USB20DRD_USER		4
+
+#define CLK_GOUT_FSYS_CMU_PCLK			5
+#define CLK_GOUT_FSYS_MMC_CARD_SDCLKIN		6
+#define CLK_GOUT_FSYS_MMC_EMBD_SDCLKIN		7
+#define CLK_GOUT_FSYS_OSCCLK			8
+#define CLK_GOUT_FSYS_USB20DRD_REFCLK		9
+#define CLK_GOUT_FSYS_USB20DRD_PHY_REFCLK	10
+#define CLK_GOUT_FSYS_D_TZPC_PCLK		11
+#define CLK_GOUT_FSYS_GPIO_PCLK			12
+#define CLK_GOUT_FSYS_MMC_CARD_ACLK		13
+#define CLK_GOUT_FSYS_MMC_EMBD_ACLK		14
+#define CLK_GOUT_FSYS_PPMU_ACLK			15
+#define CLK_GOUT_FSYS_PPMU_PCLK			16
+#define CLK_GOUT_FSYS_BUS_CLK			17
+#define CLK_GOUT_FSYS_SLH_AXI_MI_P_CLK		18
+#define CLK_GOUT_FSYS_SLH_AXI_SI_D_CLK		19
+#define CLK_GOUT_FSYS_SYSREG_PCLK		20
+#define CLK_GOUT_FSYS_USB20DRD_ACLK_PHYCTRL	21
+#define CLK_GOUT_FSYS_USB20DRD_BUS_CLK_EARLY	22
+#define CLK_GOUT_FSYS_US_64TO128_ACLK		23
+#define CLK_GOUT_FSYS_XIU_D_ACLK		24
+#define CLK_GOUT_FSYS_XIU_P_ACLK		25
+
+#endif /* _DT_BINDINGS_CLOCK_EXYNOS5515_H */

-- 
2.54.0



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

* [PATCH 1/3] dt-bindings: clock: Add Exynos5515 SoC
@ 2026-08-17 10:17   ` Aiden Isik
  0 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik @ 2026-08-17 10:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
	Brian Masney, Rob Herring, Conor Dooley, Kees Cook,
	Gustavo A. R. Silva
  Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, linux-hardening, Aiden Isik

Add devicetree documentation for the Exynos5515 SoC's CMUs.

Add device tree bindings for the following CMUs:
- CMU_TOP
- CMU_PERI
- CMU_FSYS

Signed-off-by: Aiden Isik <aidenisik+git@member.fsf.org>
---
 .../bindings/clock/samsung,exynos5515-cmu.yaml     | 145 ++++++++++++++++
 include/dt-bindings/clock/samsung,exynos5515-cmu.h | 191 +++++++++++++++++++++
 2 files changed, 336 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml
new file mode 100644
index 000000000000..1be8962cda1c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos5515-cmu.yaml
@@ -0,0 +1,145 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos5515-cmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos5515 SoC clock controller
+
+maintainers:
+  - Aiden Isik <aidenisik+git@member.fsf.org>
+  - Chanwoo Choi <cw00.choi@samsung.com>
+  - Krzysztof Kozlowski <krzk@kernel.org>
+
+description: |
+  Exynos5515 clock controller is comprised of several CMU units, generating
+  clocks for different domains. Those CMU units are modeled as separate device
+  tree nodes, and might depend on each other. The root clock in that root tree
+  is an external clock: OSCCLK (26 MHz). This external clock must be defined
+  as a fixed-rate clock in dts.
+
+  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
+  dividers; all other clocks of function blocks (other CMUs) are usually
+  derived from CMU_TOP.
+
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All clocks available for usage
+  in clock consumer nodes are defined as preprocessor macros in
+  'include/dt-bindings/clock/samsung,exynos5515-cmu.h' header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos5515-cmu-fsys
+      - samsung,exynos5515-cmu-peri
+      - samsung,exynos5515-cmu-top
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  samsung,sysreg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to system registers interface.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#clock-cells"
+  - reg
+  - samsung,sysreg
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos5515-cmu-fsys
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26MHz)
+            - description: CMU_FSYS BUS clock (from CMU_TOP)
+            - description: CMU_FSYS MMC card clock (from CMU_TOP)
+            - description: CMU_FSYS MMC embedded clock (from CMU_TOP)
+            - description: CMU_FSYS USB20DRD clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: bus
+            - const: mmc_card
+            - const: mmc_embd
+            - const: usb20drd
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos5515-cmu-peri
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26MHz)
+            - description: CMU_PERI BUS clock (from CMU_TOP)
+            - description: CMU_PERI IP clock (from CMU_TOP)
+            - description: CMU_PERI UART clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: bus
+            - const: ip
+            - const: uart
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5515-cmu-top
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+
+        clock-names:
+          items:
+            - const: oscclk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/samsung,exynos5515-cmu.h>
+
+    cmu_top: clock-controller@15410000 {
+        compatible = "samsung,exynos5515-cmu-top";
+        reg = <0x15410000 0x10000>;
+        #clock-cells = <1>;
+
+        clocks = <&oscclk>;
+        clock-names = "oscclk";
+        samsung,sysreg = <&sysreg_top>;
+    };
+
+...
diff --git a/include/dt-bindings/clock/samsung,exynos5515-cmu.h b/include/dt-bindings/clock/samsung,exynos5515-cmu.h
new file mode 100644
index 000000000000..2877d3681b55
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,exynos5515-cmu.h
@@ -0,0 +1,191 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2026 Aiden Isik <aidenisik+git@member.fsf.org>
+ * Author: Aiden Isik <aidenisik+git@member.fsf.org>
+ *
+ * Device Tree binding constants for Exynos5515 clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS5515_H
+#define _DT_BINDINGS_CLOCK_EXYNOS5515_H
+
+/* CMU_TOP */
+#define CLK_FOUT_AUD_PLL			1
+#define CLK_FOUT_SHARED0_PLL			2
+#define CLK_FOUT_SHARED1_PLL			3
+
+#define CLK_MOUT_CMU_APM_BUS			4
+#define CLK_MOUT_CMU_CORE_BUS			5
+#define CLK_MOUT_CMU_CORE_SSS			6
+#define CLK_MOUT_CMU_CPUCL0_BUSP		7
+#define CLK_MOUT_CMU_CPUCL0_CPU			8
+#define CLK_MOUT_CMU_CPUCL0_DBG			9
+#define CLK_MOUT_CMU_DPU_AUDIF			10
+#define CLK_MOUT_CMU_DPU_AUD_BUS		11
+#define CLK_MOUT_CMU_DPU_AUD_CPU		12
+#define CLK_MOUT_CMU_DPU_BUS			13
+#define CLK_MOUT_CMU_FSYS_BUS			14
+#define CLK_MOUT_CMU_FSYS_MMC_CARD		15
+#define CLK_MOUT_CMU_FSYS_MMC_EMBD		16
+#define CLK_MOUT_CMU_FSYS_USB20DRD		17
+#define CLK_MOUT_CMU_G3D_BUS			18
+#define CLK_MOUT_CMU_MFC_BUS			19
+#define CLK_MOUT_CMU_MIF_BUSP			20
+#define CLK_MOUT_CMU_MIF_SWITCH			21
+#define CLK_MOUT_CMU_MODEM_SHARED1		22
+#define CLK_MOUT_CMU_PERI_BUS			23
+#define CLK_MOUT_CMU_PERI_IP			24
+#define CLK_MOUT_CMU_PERI_UART			25
+#define CLK_MOUT_CMU_CMUREF			26
+
+#define CLK_DOUT_AP2CP_SHARED0_PLL		27
+#define CLK_DOUT_AP2CP_SHARED1_PLL		28
+#define CLK_DOUT_AP2CP_SHARED2_PLL		29
+#define CLK_DOUT_CMU_APM_BUS			30
+#define CLK_DOUT_CMU_CMU_BOOST			31
+#define CLK_DOUT_CMU_CORE_BUS			32
+#define CLK_DOUT_CMU_CORE_SSS			33
+#define CLK_DOUT_CMU_CPUCL0_BUSP		34
+#define CLK_DOUT_CMU_CPUCL0_CPU			35
+#define CLK_DOUT_CMU_CPUCL0_DBG			36
+#define CLK_DOUT_CMU_DPU_AUDIF			37
+#define CLK_DOUT_CMU_DPU_AUD_BUS		38
+#define CLK_DOUT_CMU_DPU_AUD_CPU		39
+#define CLK_DOUT_CMU_DPU_BUS			40
+#define CLK_DOUT_CMU_FSYS_BUS			41
+#define CLK_DOUT_CMU_FSYS_MMC_CARD		42
+#define CLK_DOUT_CMU_FSYS_MMC_EMBD		43
+#define CLK_DOUT_CMU_FSYS_USB20DRD		44
+#define CLK_DOUT_CMU_G3D_BUS			45
+#define CLK_DOUT_CMU_MFC_BUS			46
+#define CLK_DOUT_CMU_MIF_BUSP			47
+#define CLK_DOUT_CMU_PERI_BUS			48
+#define CLK_DOUT_CMU_PERI_IP			49
+#define CLK_DOUT_CMU_PERI_UART			50
+#define CLK_DOUT_CMU_CMUREF			51
+
+#define CLK_DOUT_SHARED0_DIV2			52
+#define CLK_DOUT_SHARED0_DIV3			53
+#define CLK_DOUT_SHARED0_DIV4			54
+#define CLK_DOUT_SHARED1_DIV2			55
+#define CLK_DOUT_SHARED1_DIV3			56
+#define CLK_DOUT_SHARED1_DIV4			57
+#define CLK_DOUT_AUD_DIV2			58
+#define CLK_DOUT_AUD_DIV3			59
+#define CLK_DOUT_AUD_DIV4			60
+
+#define CLK_GOUT_CMU_MIF_SWITCH			61
+#define CLK_GOUT_CMU_APM_BUS			62
+#define CLK_GOUT_CMU_CORE_BUS			63
+#define CLK_GOUT_CMU_CORE_SSS			64
+#define CLK_GOUT_CMU_CPUCL0_BUSP		65
+#define CLK_GOUT_CMU_CPUCL0_CPU			66
+#define CLK_GOUT_CMU_CPUCL0_DBG			67
+#define CLK_GOUT_CMU_DPU_AUDIF			68
+#define CLK_GOUT_CMU_DPU_AUD_BUS		69
+#define CLK_GOUT_CMU_DPU_AUD_CPU		70
+#define CLK_GOUT_CMU_DPU_BUS			71
+#define CLK_GOUT_CMU_FSYS_BUS			72
+#define CLK_GOUT_CMU_FSYS_MMC_CARD		73
+#define CLK_GOUT_CMU_FSYS_MMC_EMBD		74
+#define CLK_GOUT_CMU_FSYS_USB20DRD		75
+#define CLK_GOUT_CMU_G3D_BUS			76
+#define CLK_GOUT_CMU_MFC_BUS			77
+#define CLK_GOUT_CMU_MIF_BUSP			78
+#define CLK_GOUT_CMU_MODEM_SHARED0		79
+#define CLK_GOUT_CMU_MODEM_SHARED1		80
+#define CLK_GOUT_CMU_MODEM_SHARED2		81
+#define CLK_GOUT_CMU_PERI_BUS			82
+#define CLK_GOUT_CMU_PERI_IP			83
+#define CLK_GOUT_CMU_PERI_UART			84
+
+/* CMU_PERI */
+#define CLK_MOUT_PLL_PERI_BUS_USER		1
+#define CLK_MOUT_PLL_PERI_IP_USER		2
+#define CLK_MOUT_PLL_PERI_UART_USER		3
+#define CLK_MOUT_PERI_SPI			4
+#define CLK_MOUT_PERI_USI00_USI			5
+
+#define CLK_DOUT_PERI_OTP			6
+
+#define CLK_DOUT_PERI_I2C_0			7
+#define CLK_DOUT_PERI_I2C_1			8
+#define CLK_DOUT_PERI_I2C_2			9
+#define CLK_DOUT_PERI_I2C_3			10
+#define CLK_DOUT_PERI_SPI			11
+#define CLK_DOUT_PERI_USI00_I2C			12
+#define CLK_DOUT_PERI_USI00_USI			13
+
+#define CLK_GOUT_PERI_BUSIF_TMU_PCLK		14
+#define CLK_GOUT_PERI_D_TZPC_PCLK		15
+#define CLK_GOUT_PERI_GPIO_PCLK			16
+#define CLK_GOUT_PERI_I2C_0_IPCLK		17
+#define CLK_GOUT_PERI_I2C_0_PCLK		18
+#define CLK_GOUT_PERI_I2C_1_IPCLK		19
+#define CLK_GOUT_PERI_I2C_1_PCLK		20
+#define CLK_GOUT_PERI_I2C_2_IPCLK		21
+#define CLK_GOUT_PERI_I2C_2_PCLK		22
+#define CLK_GOUT_PERI_I2C_3_IPCLK		23
+#define CLK_GOUT_PERI_I2C_3_PCLK		24
+#define CLK_GOUT_PERI_MCT_PCLK			25
+#define CLK_GOUT_PERI_OTP_OSCCLK		26
+#define CLK_GOUT_PERI_OTP_PCLK			27
+#define CLK_GOUT_PERI_CMU_PCLK			28
+#define CLK_GOUT_PERI_PWM_MOTOR_PCLK		29
+#define CLK_GOUT_PERI_BUS_CLK			30
+#define CLK_GOUT_PERI_I2C_0_CLK			31
+#define CLK_GOUT_PERI_I2C_1_CLK			32
+#define CLK_GOUT_PERI_I2C_2_CLK			33
+#define CLK_GOUT_PERI_I2C_3_CLK			34
+#define CLK_GOUT_PERI_OSCCLK			35
+#define CLK_GOUT_PERI_SPI_CLK			36
+#define CLK_GOUT_PERI_UART_CLK			37
+#define CLK_GOUT_PERI_USI00_I2C_CLK		38
+#define CLK_GOUT_PERI_USI00_USI_CLK		39
+#define CLK_GOUT_PERI_SLH_AXI_MI_P_CLK		40
+#define CLK_GOUT_PERI_SYSREG_PCLK		41
+#define CLK_GOUT_PERI_USI00_I2C_IPCLK		42
+#define CLK_GOUT_PERI_USI00_I2C_PCLK		43
+#define CLK_GOUT_PERI_USI00_USI_IPCLK		44
+#define CLK_GOUT_PERI_USI00_USI_PCLK		45
+#define CLK_GOUT_PERI_USI_SPI_IPCLK		46
+#define CLK_GOUT_PERI_USI_SPI_PCLK		47
+#define CLK_GOUT_PERI_USI_UART_IPCLK		48
+#define CLK_GOUT_PERI_USI_UART_PCLK		49
+#define CLK_GOUT_PERI_WDT0_PCLK			50
+#define CLK_GOUT_PERI_WDT1_PCLK			51
+#define CLK_GOUT_PERI_I2C_0			52
+#define CLK_GOUT_PERI_I2C_1			53
+#define CLK_GOUT_PERI_I2C_2			54
+#define CLK_GOUT_PERI_I2C_3			55
+#define CLK_GOUT_PERI_USI00_I2C			56
+
+/* CMU_FSYS */
+#define CLK_MOUT_PLL_FSYS_BUS_USER		1
+#define CLK_MOUT_PLL_FSYS_MMC_CARD_USER		2
+#define CLK_MOUT_PLL_FSYS_MMC_EMBD_USER		3
+#define CLK_MOUT_PLL_FSYS_USB20DRD_USER		4
+
+#define CLK_GOUT_FSYS_CMU_PCLK			5
+#define CLK_GOUT_FSYS_MMC_CARD_SDCLKIN		6
+#define CLK_GOUT_FSYS_MMC_EMBD_SDCLKIN		7
+#define CLK_GOUT_FSYS_OSCCLK			8
+#define CLK_GOUT_FSYS_USB20DRD_REFCLK		9
+#define CLK_GOUT_FSYS_USB20DRD_PHY_REFCLK	10
+#define CLK_GOUT_FSYS_D_TZPC_PCLK		11
+#define CLK_GOUT_FSYS_GPIO_PCLK			12
+#define CLK_GOUT_FSYS_MMC_CARD_ACLK		13
+#define CLK_GOUT_FSYS_MMC_EMBD_ACLK		14
+#define CLK_GOUT_FSYS_PPMU_ACLK			15
+#define CLK_GOUT_FSYS_PPMU_PCLK			16
+#define CLK_GOUT_FSYS_BUS_CLK			17
+#define CLK_GOUT_FSYS_SLH_AXI_MI_P_CLK		18
+#define CLK_GOUT_FSYS_SLH_AXI_SI_D_CLK		19
+#define CLK_GOUT_FSYS_SYSREG_PCLK		20
+#define CLK_GOUT_FSYS_USB20DRD_ACLK_PHYCTRL	21
+#define CLK_GOUT_FSYS_USB20DRD_BUS_CLK_EARLY	22
+#define CLK_GOUT_FSYS_US_64TO128_ACLK		23
+#define CLK_GOUT_FSYS_XIU_D_ACLK		24
+#define CLK_GOUT_FSYS_XIU_P_ACLK		25
+
+#endif /* _DT_BINDINGS_CLOCK_EXYNOS5515_H */

-- 
2.54.0


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

* [PATCH 2/3] clk: samsung: clk-pll: Add support for pll_309
  2026-08-17 10:17 ` Aiden Isik
@ 2026-08-17 10:17   ` Aiden Isik
  -1 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik via B4 Relay @ 2026-08-17 10:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
	Brian Masney, Rob Herring, Conor Dooley, Kees Cook,
	Gustavo A. R. Silva
  Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, linux-hardening, Aiden Isik

From: Aiden Isik <aidenisik@member.fsf.org>

pll_309 (referred to in the downstream kernel sources as frd_309_rpll) is
one of two PLLs used in the Exynos5515 SoC. It is an integer/fractional
PLL with an FVCO of 600-2400MHz.

It has the same locktime (500), and kdiv/mdiv/pdiv/sdiv masks and shifts
as pll_531x, so it can be handled in exactly the same way.

When defining a PLL, the "con" parameter should be set to the CON3
register, like this:

PLL(pll_309, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk",
    PLL_LOCKTIME_PLL_AUD, PLL_CON3_PLL_AUD, NULL),

Signed-off-by: Aiden Isik <aidenisik+git@member.fsf.org>
---
 drivers/clk/samsung/clk-pll.c | 57 +++++++++++++++++++++++--------------------
 drivers/clk/samsung/clk-pll.h |  1 +
 2 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index e74552846ba3..8b1474aeaf0c 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -28,7 +28,7 @@ struct samsung_clk_pll {
 	unsigned short		lock_offs;
 	enum samsung_pll_type	type;
 	unsigned int		rate_count;
-	struct samsung_pll_rate_table rate_table[] __counted_by(rate_count);
+	const struct samsung_pll_rate_table *rate_table;
 };
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
@@ -1593,32 +1593,35 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 {
 	struct samsung_clk_pll *pll;
 	struct clk_init_data init;
-	unsigned int len = 0;
-	int ret;
+	int ret, len;
 
-	if (pll_clk->rate_table) {
-		/* find count of rates in rate_table */
-		while (pll_clk->rate_table[len].rate != 0)
-			len++;
-	}
-
-	pll = kzalloc_flex(*pll, rate_table, len);
+	pll = kzalloc_obj(*pll);
 	if (!pll) {
 		pr_err("%s: could not allocate pll clk %s\n",
 			__func__, pll_clk->name);
 		return;
 	}
 
-	pll->rate_count = len;
-	if (len)
-		memcpy(pll->rate_table, pll_clk->rate_table,
-		       len * sizeof(*pll->rate_table));
-
 	init.name = pll_clk->name;
 	init.flags = pll_clk->flags;
 	init.parent_names = &pll_clk->parent_name;
 	init.num_parents = 1;
 
+	if (pll_clk->rate_table) {
+		/* find count of rates in rate_table */
+		for (len = 0; pll_clk->rate_table[len].rate != 0; )
+			len++;
+
+		pll->rate_count = len;
+		pll->rate_table = kmemdup_array(pll_clk->rate_table,
+						pll->rate_count,
+						sizeof(*pll->rate_table),
+						GFP_KERNEL);
+		WARN(!pll->rate_table,
+			"%s: could not allocate rate table for %s\n",
+			__func__, pll_clk->name);
+	}
+
 	switch (pll_clk->type) {
 	case pll_2126:
 		init.ops = &samsung_pll2126_clk_ops;
@@ -1637,7 +1640,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_a9fracm:
 		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll35xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll35xx_clk_ops;
@@ -1656,7 +1659,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_0732x:
 		pll->enable_offs = PLL0822X_ENABLE_SHIFT;
 		pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll0822x_clk_min_ops;
 		else
 			init.ops = &samsung_pll0822x_clk_ops;
@@ -1666,7 +1669,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 		break;
 	case pll_4502:
 	case pll_4508:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll45xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll45xx_clk_ops;
@@ -1676,7 +1679,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_2650:
 		pll->enable_offs = PLL36XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll36xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll36xx_clk_ops;
@@ -1684,7 +1687,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_0831x:
 		pll->enable_offs = PLL0831X_ENABLE_SHIFT;
 		pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll0831x_clk_min_ops;
 		else
 			init.ops = &samsung_pll0831x_clk_ops;
@@ -1700,7 +1703,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_4650:
 	case pll_4650c:
 	case pll_1460x:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll46xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll46xx_clk_ops;
@@ -1709,29 +1712,30 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 		init.ops = &samsung_pll2550x_clk_ops;
 		break;
 	case pll_2550xx:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll2550xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll2550xx_clk_ops;
 		break;
 	case pll_2650x:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll2650x_clk_min_ops;
 		else
 			init.ops = &samsung_pll2650x_clk_ops;
 		break;
 	case pll_2650xx:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll2650xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll2650xx_clk_ops;
 		break;
 	case pll_531x:
 	case pll_4311:
+	case pll_309:
 		init.ops = &samsung_pll531x_clk_ops;
 		break;
 	case pll_1031x:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll1031x_clk_min_ops;
 		else
 			init.ops = &samsung_pll1031x_clk_ops;
@@ -1739,7 +1743,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_a9fraco:
 		pll->enable_offs = PLLA9FRACO_ENABLE_SHIFT;
 		pll->lock_offs = PLLA9FRACO_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_a9fraco_clk_min_ops;
 		else
 			init.ops = &samsung_a9fraco_clk_ops;
@@ -1758,6 +1762,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	if (ret) {
 		pr_err("%s: failed to register pll clock %s : %d\n",
 			__func__, pll_clk->name, ret);
+		kfree(pll->rate_table);
 		kfree(pll);
 		return;
 	}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index d6eb3246611b..2457cf47c109 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -53,6 +53,7 @@ enum samsung_pll_type {
 	pll_1031x,
 	pll_a9fracm,
 	pll_a9fraco,
+	pll_309,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \

-- 
2.54.0



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

* [PATCH 2/3] clk: samsung: clk-pll: Add support for pll_309
@ 2026-08-17 10:17   ` Aiden Isik
  0 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik @ 2026-08-17 10:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
	Brian Masney, Rob Herring, Conor Dooley, Kees Cook,
	Gustavo A. R. Silva
  Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, linux-hardening, Aiden Isik

pll_309 (referred to in the downstream kernel sources as frd_309_rpll) is
one of two PLLs used in the Exynos5515 SoC. It is an integer/fractional
PLL with an FVCO of 600-2400MHz.

It has the same locktime (500), and kdiv/mdiv/pdiv/sdiv masks and shifts
as pll_531x, so it can be handled in exactly the same way.

When defining a PLL, the "con" parameter should be set to the CON3
register, like this:

PLL(pll_309, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk",
    PLL_LOCKTIME_PLL_AUD, PLL_CON3_PLL_AUD, NULL),

Signed-off-by: Aiden Isik <aidenisik+git@member.fsf.org>
---
 drivers/clk/samsung/clk-pll.c | 57 +++++++++++++++++++++++--------------------
 drivers/clk/samsung/clk-pll.h |  1 +
 2 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index e74552846ba3..8b1474aeaf0c 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -28,7 +28,7 @@ struct samsung_clk_pll {
 	unsigned short		lock_offs;
 	enum samsung_pll_type	type;
 	unsigned int		rate_count;
-	struct samsung_pll_rate_table rate_table[] __counted_by(rate_count);
+	const struct samsung_pll_rate_table *rate_table;
 };
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
@@ -1593,32 +1593,35 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 {
 	struct samsung_clk_pll *pll;
 	struct clk_init_data init;
-	unsigned int len = 0;
-	int ret;
+	int ret, len;
 
-	if (pll_clk->rate_table) {
-		/* find count of rates in rate_table */
-		while (pll_clk->rate_table[len].rate != 0)
-			len++;
-	}
-
-	pll = kzalloc_flex(*pll, rate_table, len);
+	pll = kzalloc_obj(*pll);
 	if (!pll) {
 		pr_err("%s: could not allocate pll clk %s\n",
 			__func__, pll_clk->name);
 		return;
 	}
 
-	pll->rate_count = len;
-	if (len)
-		memcpy(pll->rate_table, pll_clk->rate_table,
-		       len * sizeof(*pll->rate_table));
-
 	init.name = pll_clk->name;
 	init.flags = pll_clk->flags;
 	init.parent_names = &pll_clk->parent_name;
 	init.num_parents = 1;
 
+	if (pll_clk->rate_table) {
+		/* find count of rates in rate_table */
+		for (len = 0; pll_clk->rate_table[len].rate != 0; )
+			len++;
+
+		pll->rate_count = len;
+		pll->rate_table = kmemdup_array(pll_clk->rate_table,
+						pll->rate_count,
+						sizeof(*pll->rate_table),
+						GFP_KERNEL);
+		WARN(!pll->rate_table,
+			"%s: could not allocate rate table for %s\n",
+			__func__, pll_clk->name);
+	}
+
 	switch (pll_clk->type) {
 	case pll_2126:
 		init.ops = &samsung_pll2126_clk_ops;
@@ -1637,7 +1640,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_a9fracm:
 		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll35xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll35xx_clk_ops;
@@ -1656,7 +1659,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_0732x:
 		pll->enable_offs = PLL0822X_ENABLE_SHIFT;
 		pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll0822x_clk_min_ops;
 		else
 			init.ops = &samsung_pll0822x_clk_ops;
@@ -1666,7 +1669,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 		break;
 	case pll_4502:
 	case pll_4508:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll45xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll45xx_clk_ops;
@@ -1676,7 +1679,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_2650:
 		pll->enable_offs = PLL36XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll36xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll36xx_clk_ops;
@@ -1684,7 +1687,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_0831x:
 		pll->enable_offs = PLL0831X_ENABLE_SHIFT;
 		pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll0831x_clk_min_ops;
 		else
 			init.ops = &samsung_pll0831x_clk_ops;
@@ -1700,7 +1703,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_4650:
 	case pll_4650c:
 	case pll_1460x:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll46xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll46xx_clk_ops;
@@ -1709,29 +1712,30 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 		init.ops = &samsung_pll2550x_clk_ops;
 		break;
 	case pll_2550xx:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll2550xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll2550xx_clk_ops;
 		break;
 	case pll_2650x:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll2650x_clk_min_ops;
 		else
 			init.ops = &samsung_pll2650x_clk_ops;
 		break;
 	case pll_2650xx:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll2650xx_clk_min_ops;
 		else
 			init.ops = &samsung_pll2650xx_clk_ops;
 		break;
 	case pll_531x:
 	case pll_4311:
+	case pll_309:
 		init.ops = &samsung_pll531x_clk_ops;
 		break;
 	case pll_1031x:
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_pll1031x_clk_min_ops;
 		else
 			init.ops = &samsung_pll1031x_clk_ops;
@@ -1739,7 +1743,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_a9fraco:
 		pll->enable_offs = PLLA9FRACO_ENABLE_SHIFT;
 		pll->lock_offs = PLLA9FRACO_LOCK_STAT_SHIFT;
-		if (!pll->rate_count)
+		if (!pll->rate_table)
 			init.ops = &samsung_a9fraco_clk_min_ops;
 		else
 			init.ops = &samsung_a9fraco_clk_ops;
@@ -1758,6 +1762,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	if (ret) {
 		pr_err("%s: failed to register pll clock %s : %d\n",
 			__func__, pll_clk->name, ret);
+		kfree(pll->rate_table);
 		kfree(pll);
 		return;
 	}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index d6eb3246611b..2457cf47c109 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -53,6 +53,7 @@ enum samsung_pll_type {
 	pll_1031x,
 	pll_a9fracm,
 	pll_a9fraco,
+	pll_309,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \

-- 
2.54.0


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

* [PATCH 3/3] clk: samsung: Introduce Exynos5515 clock driver
  2026-08-17 10:17 ` Aiden Isik
@ 2026-08-17 10:17   ` Aiden Isik
  -1 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik via B4 Relay @ 2026-08-17 10:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
	Brian Masney, Rob Herring, Conor Dooley, Kees Cook,
	Gustavo A. R. Silva
  Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, linux-hardening, Aiden Isik

From: Aiden Isik <aidenisik@member.fsf.org>

CMU_TOP is the top level clock management unit which contains PLLs,
muxes, dividers and gates that feed the other clock management units.

CMU_PERI provides clocks for USI blocks and their children, PWM, MCT,
and watchdog timers.

CMU_FSYS provides clocks for MMC, USB, GPIO, etc.

More blocks will be added as device drivers which utilise them are added.

Signed-off-by: Aiden Isik <aidenisik+git@member.fsf.org>
---
 drivers/clk/samsung/Makefile         |    1 +
 drivers/clk/samsung/clk-exynos5515.c | 1485 ++++++++++++++++++++++++++++++++++
 2 files changed, 1486 insertions(+)

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index b3c4ef4e0dbf..b3e994bd525d 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
 obj-$(CONFIG_EXYNOS_CLKOUT)	+= clk-exynos-clkout.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos-arm64.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos2200.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos5515.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7870.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7885.o
diff --git a/drivers/clk/samsung/clk-exynos5515.c b/drivers/clk/samsung/clk-exynos5515.c
new file mode 100644
index 000000000000..f989a13f1a57
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos5515.c
@@ -0,0 +1,1485 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Aiden Isik <aidenisik+git@member.fsf.org>
+ * Author: Aiden Isik <aidenisik+git@member.fsf.org>
+ *
+ * Common Clock Framework support for Exynos5515 SoC.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/samsung,exynos5515-cmu.h>
+
+#include "clk.h"
+#include "clk-exynos-arm64.h"
+#include "clk-pll.h"
+
+/* NOTE: Must be equal to the last clock ID increased by one */
+#define CLKS_NR_TOP	(CLK_GOUT_CMU_PERI_UART + 1)
+#define CLKS_NR_PERI	(CLK_GOUT_PERI_USI00_I2C + 1)
+#define CLKS_NR_FSYS	(CLK_GOUT_FSYS_XIU_P_ACLK + 1)
+
+#define EXYNOS5515_GATE_DBG_OFFSET	0x4000
+#define EXYNOS5515_DRCG_EN_OFFSET	0x0104
+#define EXYNOS5515_MEMCLK_OFFSET	0x0108
+
+/* ---- CMU_TOP ------------------------------------------------------------- */
+
+/*
+ * CMU_TOP:	0x15410000
+ * SYSREG_TOP:	0x15430000
+ */
+
+/* Register Offset definitions for CMU_TOP */
+#define PLL_LOCKTIME_PLL_AUD			0x0000
+#define PLL_LOCKTIME_PLL_SHARED0		0x0004
+#define PLL_LOCKTIME_PLL_SHARED1		0x0008
+#define PLL_CON3_PLL_AUD			0x010c
+#define PLL_CON8_PLL_AUD			0x0120
+#define PLL_CON9_PLL_AUD			0x0124
+#define PLL_CON3_PLL_SHARED0			0x014c
+#define PLL_CON8_PLL_SHARED0			0x0160
+#define PLL_CON9_PLL_SHARED0			0x0164
+#define PLL_CON3_PLL_SHARED1			0x018c
+#define PLL_CON8_PLL_SHARED1			0x01a0
+#define PLL_CON9_PLL_SHARED1			0x01a4
+#define CMU_CMU_TOP_CONTROLLER_OPTION		0x0800
+#define CLK_CON_MUX_MUX_CLKCMU_APM_BUS		0x1000
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS		0x1004
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS		0x1008
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP	0x100c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU	0x1010
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG	0x1014
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF	0x1018
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS	0x101c
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU	0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_BUS		0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS		0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD	0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD	0x1030
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD	0x1034
+#define CLK_CON_MUX_MUX_CLKCMU_G3D_BUS		0x1038
+#define CLK_CON_MUX_MUX_CLKCMU_MFC_BUS		0x103c
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP		0x1040
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH	0x1044
+#define CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1	0x1048
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS		0x104c
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_IP		0x1050
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART	0x1054
+#define CLK_CON_MUX_MUX_CMU_CMUREF		0x1058
+#define CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK	0x1800
+#define CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK	0x1804
+#define CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK	0x1808
+#define CLK_CON_DIV_CLKCMU_APM_BUS		0x180c
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST		0x1810
+#define CLK_CON_DIV_CLKCMU_CORE_BUS		0x1814
+#define CLK_CON_DIV_CLKCMU_CORE_SSS		0x1818
+#define CLK_CON_DIV_CLKCMU_CPUCL0_BUSP		0x181c
+#define CLK_CON_DIV_CLKCMU_CPUCL0_CPU		0x1820
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG		0x1824
+#define CLK_CON_DIV_CLKCMU_DPU_AUDIF		0x1828
+#define CLK_CON_DIV_CLKCMU_DPU_AUD_BUS		0x182c
+#define CLK_CON_DIV_CLKCMU_DPU_AUD_CPU		0x1830
+#define CLK_CON_DIV_CLKCMU_DPU_BUS		0x1834
+#define CLK_CON_DIV_CLKCMU_FSYS_BUS		0x1838
+#define CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD	0x183c
+#define CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD	0x1840
+#define CLK_CON_DIV_CLKCMU_FSYS_USB20DRD	0x1844
+#define CLK_CON_DIV_CLKCMU_G3D_BUS		0x1848
+#define CLK_CON_DIV_CLKCMU_MFC_BUS		0x184c
+#define CLK_CON_DIV_CLKCMU_MIF_BUSP		0x1850
+#define CLK_CON_DIV_CLKCMU_PERI_BUS		0x1854
+#define CLK_CON_DIV_CLKCMU_PERI_IP		0x1858
+#define CLK_CON_DIV_CLKCMU_PERI_UART		0x185c
+#define CLK_CON_DIV_DIV_CLK_CMU_CMUREF		0x1860
+#define CLK_CON_GAT_CLKCMU_MIF_SWITCH		0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_APM_BUS		0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS	0x2038
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS	0x203c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP	0x2040
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU	0x2044
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG	0x2048
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF	0x204c
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS	0x2050
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU	0x2054
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_BUS		0x2058
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS	0x205c
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD	0x2060
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD	0x2064
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD	0x2068
+#define CLK_CON_GAT_GATE_CLKCMU_G3D_BUS		0x206c
+#define CLK_CON_GAT_GATE_CLKCMU_MFC_BUS		0x2070
+#define CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP	0x2074
+#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0	0x2078
+#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1	0x207c
+#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2	0x2080
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS	0x2084
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_IP		0x2088
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART	0x208c
+
+static const unsigned long top_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_AUD,
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_CON3_PLL_AUD,
+	PLL_CON8_PLL_AUD,
+	PLL_CON9_PLL_AUD,
+	PLL_CON3_PLL_SHARED0,
+	PLL_CON8_PLL_SHARED0,
+	PLL_CON9_PLL_SHARED0,
+	PLL_CON3_PLL_SHARED1,
+	PLL_CON8_PLL_SHARED1,
+	PLL_CON9_PLL_SHARED1,
+	CMU_CMU_TOP_CONTROLLER_OPTION,
+	CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD,
+	CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD,
+	CLK_CON_MUX_MUX_CLKCMU_G3D_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MFC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1,
+	CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
+	CLK_CON_MUX_MUX_CMU_CMUREF,
+	CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK,
+	CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK,
+	CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK,
+	CLK_CON_DIV_CLKCMU_APM_BUS,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST,
+	CLK_CON_DIV_CLKCMU_CORE_BUS,
+	CLK_CON_DIV_CLKCMU_CORE_SSS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_BUSP,
+	CLK_CON_DIV_CLKCMU_CPUCL0_CPU,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG,
+	CLK_CON_DIV_CLKCMU_DPU_AUDIF,
+	CLK_CON_DIV_CLKCMU_DPU_AUD_BUS,
+	CLK_CON_DIV_CLKCMU_DPU_AUD_CPU,
+	CLK_CON_DIV_CLKCMU_DPU_BUS,
+	CLK_CON_DIV_CLKCMU_FSYS_BUS,
+	CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD,
+	CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD,
+	CLK_CON_DIV_CLKCMU_FSYS_USB20DRD,
+	CLK_CON_DIV_CLKCMU_G3D_BUS,
+	CLK_CON_DIV_CLKCMU_MFC_BUS,
+	CLK_CON_DIV_CLKCMU_MIF_BUSP,
+	CLK_CON_DIV_CLKCMU_PERI_BUS,
+	CLK_CON_DIV_CLKCMU_PERI_IP,
+	CLK_CON_DIV_CLKCMU_PERI_UART,
+	CLK_CON_DIV_DIV_CLK_CMU_CMUREF,
+	CLK_CON_GAT_CLKCMU_MIF_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD,
+	CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD,
+	CLK_CON_GAT_GATE_CLKCMU_G3D_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MFC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0,
+	CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1,
+	CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2,
+	CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERI_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERI_UART,
+};
+
+static const struct samsung_pll_clock top_pll_clks[] __initconst = {
+	PLL(pll_309, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_AUD, PLL_CON3_PLL_AUD, NULL),
+	PLL(pll_309, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL),
+	PLL(pll_309, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL),
+};
+
+/* Parent clock list for CMU_TOP muxes */
+PNAME(mout_cmu_cmuref_p)	= { "dout_cmu_cmuref",
+				    "oscclk" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_APM */
+PNAME(mout_cmu_apm_bus_p)	= { "dout_shared0_div2",
+				    "dout_shared0_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_CORE */
+PNAME(mout_cmu_core_bus_p)	= { "dout_aud_div3",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div3" };
+
+PNAME(mout_cmu_core_sss_p)	= { "dout_aud_div3",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_CPUCL0 */
+PNAME(mout_cmu_cpucl0_busp_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+PNAME(mout_cmu_cpucl0_cpu_p)	= { "dout_aud_div2",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3",
+				    "dout_shared1_div4",
+				    "fout_aud_pll" };
+
+PNAME(mout_cmu_cpucl0_dbg_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_DPU */
+PNAME(mout_cmu_dpu_audif_p)	= { "dout_aud_div2",
+				    "dout_aud_div3" };
+
+PNAME(mout_cmu_dpu_aud_bus_p)	= { "dout_aud_div2",
+				    "dout_aud_div3",
+				    "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+PNAME(mout_cmu_dpu_aud_cpu_p)	= { "dout_aud_div2",
+				    "dout_aud_div3",
+				    "dout_aud_div4",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3",
+				    "fout_aud_pll" };
+
+PNAME(mout_cmu_dpu_bus_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_FSYS */
+PNAME(mout_cmu_fsys_bus_p)	= { "dout_shared0_div2",
+				    "dout_shared1_div3" };
+
+PNAME(mout_cmu_fsys_mmc_card_p)	= { "dout_aud_div2",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div3",
+				    "oscclk" };
+
+PNAME(mout_cmu_fsys_mmc_embd_p)	= { "dout_aud_div2",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div3",
+				    "oscclk" };
+
+PNAME(mout_cmu_fsys_usb20drd_p)	= { "dout_shared0_div4",
+				    "oscclk" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_G3D */
+PNAME(mout_cmu_g3d_bus_p)	= { "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_MFC */
+PNAME(mout_cmu_mfc_bus_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div3",
+				    "dout_shared1_div4" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_MIF */
+PNAME(mout_cmu_mif_busp_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+PNAME(mout_cmu_mif_switch_p)	= { "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3",
+				    "dout_shared1_div4",
+				    "fout_shared0_pll",
+				    "fout_shared1_pll" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_MODEM */
+PNAME(mout_cmu_modem_shared1_p)	= { "dout_aud_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_PERI */
+PNAME(mout_cmu_peri_bus_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+PNAME(mout_cmu_peri_ip_p)	= { "dout_aud_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div4",
+				    "oscclk" };
+
+PNAME(mout_cmu_peri_uart_p)	= { "dout_aud_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div4",
+				    "oscclk" };
+
+static const struct samsung_mux_clock top_mux_clks[] __initconst = {
+	/* APM (Active Power Management) */
+	MUX(CLK_MOUT_CMU_APM_BUS, "mout_cmu_apm_bus",
+	    mout_cmu_apm_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+	    0, 1),
+
+	/* CMU (Clock Management Unit) */
+	MUX(CLK_MOUT_CMU_CMUREF, "mout_cmu_cmuref",
+	    mout_cmu_cmuref_p,
+	    CLK_CON_MUX_MUX_CMU_CMUREF,
+	    0, 1),
+
+	/* CORE */
+	MUX(CLK_MOUT_CMU_CORE_BUS, "mout_cmu_core_bus",
+	    mout_cmu_core_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CORE_SSS, "mout_cmu_core_sss",
+	    mout_cmu_core_sss_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
+	    0, 2),
+
+	/* CPUCL0 (CPU Cluster 0) */
+	MUX(CLK_MOUT_CMU_CPUCL0_BUSP, "mout_cmu_cpucl0_busp",
+	    mout_cmu_cpucl0_busp_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_CPUCL0_CPU, "mout_cmu_cpucl0_cpu",
+	    mout_cmu_cpucl0_cpu_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU,
+	    0, 3),
+	MUX(CLK_MOUT_CMU_CPUCL0_DBG, "mout_cmu_cpucl0_dbg",
+	    mout_cmu_cpucl0_dbg_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG,
+	    0, 1),
+
+	/* DPU (Display Processing Unit) */
+	MUX(CLK_MOUT_CMU_DPU_AUDIF, "mout_cmu_dpu_audif",
+	    mout_cmu_dpu_audif_p,
+	    CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_DPU_AUD_BUS, "mout_cmu_dpu_aud_bus",
+	    mout_cmu_dpu_aud_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_DPU_AUD_CPU, "mout_cmu_dpu_aud_cpu",
+	    mout_cmu_dpu_aud_cpu_p,
+	    CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU,
+	    0, 3),
+	MUX(CLK_MOUT_CMU_DPU_BUS, "mout_cmu_dpu_bus",
+	    mout_cmu_dpu_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_DPU_BUS,
+	    0, 2),
+
+	/* FSYS */
+	MUX(CLK_MOUT_CMU_FSYS_BUS, "mout_cmu_fsys_bus",
+	    mout_cmu_fsys_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_FSYS_MMC_CARD, "mout_cmu_fsys_mmc_card",
+	    mout_cmu_fsys_mmc_card_p,
+	    CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD,
+	    0, 3),
+	MUX(CLK_MOUT_CMU_FSYS_MMC_EMBD, "mout_cmu_fsys_mmc_embd",
+	    mout_cmu_fsys_mmc_embd_p,
+	    CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD,
+	    0, 3),
+	MUX(CLK_MOUT_CMU_FSYS_USB20DRD, "mout_cmu_fsys_usb20drd",
+	    mout_cmu_fsys_usb20drd_p,
+	    CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD,
+	    0, 1),
+
+	/* G3D */
+	MUX(CLK_MOUT_CMU_G3D_BUS, "mout_cmu_g3d_bus",
+	    mout_cmu_g3d_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_G3D_BUS,
+	    0, 2),
+
+	/* MFC */
+	MUX(CLK_MOUT_CMU_MFC_BUS, "mout_cmu_mfc_bus",
+	    mout_cmu_mfc_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_MFC_BUS,
+	    0, 2),
+
+	/* MIF */
+	MUX(CLK_MOUT_CMU_MIF_BUSP, "mout_cmu_mif_busp",
+	    mout_cmu_mif_busp_p,
+	    CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_MIF_SWITCH, "mout_cmu_mif_switch",
+	    mout_cmu_mif_switch_p,
+	    CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH,
+	    0, 3),
+
+	/* MODEM */
+	MUX(CLK_MOUT_CMU_MODEM_SHARED1, "mout_cmu_modem_shared1",
+	    mout_cmu_modem_shared1_p,
+	    CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1,
+	    0, 2),
+
+	/* PERI */
+	MUX(CLK_MOUT_CMU_PERI_BUS, "mout_cmu_peri_bus",
+	    mout_cmu_peri_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_PERI_IP, "mout_cmu_peri_ip",
+	    mout_cmu_peri_ip_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_PERI_UART, "mout_cmu_peri_uart",
+	    mout_cmu_peri_uart_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
+	    0, 2),
+};
+
+static const struct samsung_div_clock top_div_clks[] __initconst = {
+
+	/* APM */
+	DIV(CLK_DOUT_CMU_APM_BUS, "dout_cmu_apm_bus",
+	    "gout_cmu_apm_bus",
+	    CLK_CON_DIV_CLKCMU_APM_BUS,
+	    0, 3),
+
+	/* CMU */
+	DIV(CLK_DOUT_CMU_CMU_BOOST, "dout_cmu_cmu_boost",
+	    "fout_shared0_pll",
+	    CLK_CON_DIV_CLKCMU_CMU_BOOST,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CMUREF, "dout_cmu_cmuref",
+	    "fout_shared0_pll",
+	    CLK_CON_DIV_DIV_CLK_CMU_CMUREF,
+	    0, 2),
+
+	/* CORE */
+	DIV(CLK_DOUT_CMU_CORE_BUS, "dout_cmu_core_bus",
+	    "gout_cmu_core_bus",
+	    CLK_CON_DIV_CLKCMU_CORE_BUS,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_CORE_SSS, "dout_cmu_core_sss",
+	    "gout_cmu_core_sss",
+	    CLK_CON_DIV_CLKCMU_CORE_SSS,
+	    0, 4),
+
+	/* CPUCL0 */
+	DIV(CLK_DOUT_CMU_CPUCL0_BUSP, "dout_cmu_cpucl0_busp",
+	    "gout_cmu_cpucl0_busp",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_BUSP,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL0_CPU, "dout_cmu_cpucl0_cpu",
+	    "gout_cmu_cpucl0_cpu",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_CPU,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL0_DBG, "dout_cmu_cpucl0_dbg",
+	    "gout_cmu_cpucl0_dbg",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_DBG,
+	    0, 3),
+
+	/* DPU */
+	DIV(CLK_DOUT_CMU_DPU_AUDIF, "dout_cmu_dpu_audif",
+	    "gout_cmu_dpu_audif",
+	    CLK_CON_DIV_CLKCMU_DPU_AUDIF,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_DPU_AUD_BUS, "dout_cmu_dpu_aud_bus",
+	    "gout_cmu_dpu_aud_bus",
+	    CLK_CON_DIV_CLKCMU_DPU_AUD_BUS,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_DPU_AUD_CPU, "dout_cmu_dpu_aud_cpu",
+	    "gout_cmu_dpu_aud_cpu",
+	    CLK_CON_DIV_CLKCMU_DPU_AUD_CPU,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_DPU_BUS, "dout_cmu_dpu_bus",
+	    "gout_cmu_dpu_bus",
+	    CLK_CON_DIV_CLKCMU_DPU_BUS,
+	    0, 3),
+
+	/* FSYS */
+	DIV(CLK_DOUT_CMU_FSYS_BUS, "dout_cmu_fsys_bus",
+	    "gout_cmu_fsys_bus",
+	    CLK_CON_DIV_CLKCMU_FSYS_BUS,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_FSYS_MMC_CARD, "dout_cmu_fsys_mmc_card",
+	    "gout_cmu_fsys_mmc_card",
+	    CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_FSYS_MMC_EMBD, "dout_cmu_fsys_mmc_embd",
+	    "gout_cmu_fsys_mmc_embd",
+	    CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_FSYS_USB20DRD, "dout_cmu_fsys_usb20drd",
+	    "gout_cmu_fsys_usb20drd",
+	    CLK_CON_DIV_CLKCMU_FSYS_USB20DRD,
+	    0, 4),
+
+	/* G3D */
+	DIV(CLK_DOUT_CMU_G3D_BUS, "dout_cmu_g3d_bus",
+	    "gout_cmu_g3d_bus",
+	    CLK_CON_DIV_CLKCMU_G3D_BUS,
+	    0, 3),
+
+	/* MFC */
+	DIV(CLK_DOUT_CMU_MFC_BUS, "dout_cmu_mfc_bus",
+	    "gout_cmu_mfc_bus",
+	    CLK_CON_DIV_CLKCMU_MFC_BUS,
+	    0, 4),
+
+	/* MIF */
+	DIV(CLK_DOUT_CMU_MIF_BUSP, "dout_cmu_mif_busp",
+	    "gout_cmu_mif_busp",
+	    CLK_CON_DIV_CLKCMU_MIF_BUSP,
+	    0, 3),
+
+	/* PERI */
+	DIV(CLK_DOUT_CMU_PERI_BUS, "dout_cmu_peri_bus",
+	    "gout_cmu_peri_bus",
+	    CLK_CON_DIV_CLKCMU_PERI_BUS,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_PERI_IP, "dout_cmu_peri_ip",
+	    "gout_cmu_peri_ip",
+	    CLK_CON_DIV_CLKCMU_PERI_IP,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_PERI_UART, "dout_cmu_peri_uart",
+	    "gout_cmu_peri_uart",
+	    CLK_CON_DIV_CLKCMU_PERI_UART,
+	    0, 4),
+
+	/* SHARED */
+	DIV(CLK_DOUT_AP2CP_SHARED0_PLL, "dout_ap2cp_shared0_pll",
+	    "gout_cmu_modem_shared0",
+	    CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK,
+	    0, 3),
+	DIV(CLK_DOUT_AP2CP_SHARED1_PLL, "dout_ap2cp_shared1_pll",
+	    "gout_cmu_modem_shared1",
+	    CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK,
+	    0, 3),
+	DIV(CLK_DOUT_AP2CP_SHARED2_PLL, "dout_ap2cp_shared2_pll",
+	    "gout_cmu_modem_shared2",
+	    CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK,
+	    0, 3),
+};
+
+static const struct samsung_fixed_factor_clock top_fixed_factor_clks[] __initconst = {
+	FFACTOR(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "fout_shared0_pll",
+		1, 2, 0),
+	FFACTOR(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll",
+		1, 3, 0),
+	FFACTOR(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll",
+		1, 4, 0),
+	FFACTOR(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "fout_shared1_pll",
+		1, 2, 0),
+	FFACTOR(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll",
+		1, 3, 0),
+	FFACTOR(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll",
+		1, 4, 0),
+	FFACTOR(CLK_DOUT_AUD_DIV2, "dout_aud_div2", "fout_aud_pll",
+		1, 2, 0),
+	FFACTOR(CLK_DOUT_AUD_DIV3, "dout_aud_div3", "fout_aud_pll",
+		1, 3, 0),
+	FFACTOR(CLK_DOUT_AUD_DIV4, "dout_aud_div4", "fout_aud_pll",
+		1, 4, 0),
+};
+
+static const struct samsung_gate_clock top_gate_clks[] __initconst = {
+	/* APM */
+	GATE(CLK_GOUT_CMU_APM_BUS, "gout_cmu_apm_bus",
+	     "mout_cmu_apm_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+	     21, 0, 0),
+
+	/* CORE */
+	GATE(CLK_GOUT_CMU_CORE_BUS, "gout_cmu_core_bus",
+	     "mout_cmu_core_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CORE_SSS, "gout_cmu_core_sss",
+	     "mout_cmu_core_sss",
+	     CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
+	     21, 0, 0),
+
+	/* CPUCL0 */
+	GATE(CLK_GOUT_CMU_CPUCL0_BUSP, "gout_cmu_cpucl0_busp",
+	     "mout_cmu_cpucl0_busp",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_CPU, "gout_cmu_cpucl0_cpu",
+	     "mout_cmu_cpucl0_cpu",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_DBG, "gout_cmu_cpucl0_dbg",
+	     "mout_cmu_cpucl0_dbg",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG,
+	     21, 0, 0),
+
+	/* DPU */
+	GATE(CLK_GOUT_CMU_DPU_AUDIF, "gout_cmu_dpu_audif",
+	     "mout_cmu_dpu_audif",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_AUD_BUS, "gout_cmu_dpu_aud_bus",
+	     "mout_cmu_dpu_aud_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_AUD_CPU, "gout_cmu_dpu_aud_cpu",
+	     "mout_cmu_dpu_aud_cpu",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_BUS, "gout_cmu_dpu_bus",
+	     "mout_cmu_dpu_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_BUS,
+	     21, 0, 0),
+
+	/* FSYS */
+	GATE(CLK_GOUT_CMU_FSYS_BUS, "gout_cmu_fsys_bus",
+	     "mout_cmu_fsys_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_FSYS_MMC_CARD, "gout_cmu_fsys_mmc_card",
+	     "mout_cmu_fsys_mmc_card",
+	     CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_FSYS_MMC_EMBD, "gout_cmu_fsys_mmc_embd",
+	     "mout_cmu_fsys_mmc_embd",
+	     CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_FSYS_USB20DRD, "gout_cmu_fsys_usb20drd",
+	     "mout_cmu_fsys_usb20drd",
+	     CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD,
+	     21, 0, 0),
+
+	/* G3D */
+	GATE(CLK_GOUT_CMU_G3D_BUS, "gout_cmu_g3d_bus",
+	     "mout_cmu_g3d_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_G3D_BUS,
+	     21, 0, 0),
+
+	/* MFC */
+	GATE(CLK_GOUT_CMU_MFC_BUS, "gout_cmu_mfc_bus",
+	     "mout_cmu_mfc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_MFC_BUS,
+	     21, 0, 0),
+
+	/* MIF */
+	GATE(CLK_GOUT_CMU_MIF_SWITCH, "gout_cmu_mif_switch",
+	     "mout_cmu_mif_switch",
+	     CLK_CON_GAT_CLKCMU_MIF_SWITCH,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MIF_BUSP, "gout_cmu_mif_busp",
+	     "mout_cmu_mif_busp",
+	     CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP,
+	     21, 0, 0),
+
+	/* MODEM */
+	GATE(CLK_GOUT_CMU_MODEM_SHARED0, "gout_cmu_modem_shared0",
+	     "fout_shared0_pll",
+	     CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MODEM_SHARED1, "gout_cmu_modem_shared1",
+	     "mout_cmu_modem_shared1",
+	     CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MODEM_SHARED2, "gout_cmu_modem_shared2",
+	     "fout_shared0_pll",
+	     CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2,
+	     21, 0, 0),
+
+	/* PERI */
+	GATE(CLK_GOUT_CMU_PERI_BUS, "gout_cmu_peri_bus",
+	     "mout_cmu_peri_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERI_IP, "gout_cmu_peri_ip",
+	     "mout_cmu_peri_ip",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERI_UART, "gout_cmu_peri_uart",
+	     "mout_cmu_peri_uart",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_UART,
+	     21, 0, 0),
+};
+
+static const unsigned long drcg_sysreg[] __initconst = {
+	EXYNOS5515_DRCG_EN_OFFSET,
+};
+
+static const struct samsung_cmu_info top_cmu_info __initconst = {
+	.pll_clks		= top_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(top_pll_clks),
+	.mux_clks		= top_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(top_mux_clks),
+	.div_clks		= top_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(top_div_clks),
+	.fixed_factor_clks	= top_fixed_factor_clks,
+	.nr_fixed_factor_clks	= ARRAY_SIZE(top_fixed_factor_clks),
+	.gate_clks		= top_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(top_gate_clks),
+	.nr_clk_ids		= CLKS_NR_TOP,
+	.clk_regs		= top_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(top_clk_regs),
+	.sysreg_clk_regs	= drcg_sysreg,
+	.nr_sysreg_clk_regs	= ARRAY_SIZE(drcg_sysreg),
+	.auto_clock_gate	= true,
+	.gate_dbg_offset	= EXYNOS5515_GATE_DBG_OFFSET,
+	.option_offset		= CMU_CMU_TOP_CONTROLLER_OPTION,
+	.drcg_offset		= EXYNOS5515_DRCG_EN_OFFSET,
+};
+
+static void __init exynos5515_cmu_top_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
+}
+
+/* Register CMU_TOP early, as it's a dependency for other early domains */
+CLK_OF_DECLARE(exynos5515_cmu_top, "samsung,exynos5515-cmu-top",
+	       exynos5515_cmu_top_init);
+
+/* ---- CMU_PERI ------------------------------------------------------------ */
+
+/*
+ * CMU_PERI:	0x10030000
+ * SYSREG_PERI:	0x10020000
+ */
+
+#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER					0x0600
+#define PLL_CON1_MUX_CLKCMU_PERI_BUS_USER					0x0604
+#define PLL_CON0_MUX_CLKCMU_PERI_IP_USER					0x0610
+#define PLL_CON1_MUX_CLKCMU_PERI_IP_USER					0x0614
+#define PLL_CON0_MUX_CLKCMU_PERI_UART_USER					0x0620
+#define PLL_CON1_MUX_CLKCMU_PERI_UART_USER					0x0624
+#define PERI_CMU_PERI_CONTROLLER_OPTION						0x0800
+#define CLK_CON_MUX_MUX_CLK_PERI_SPI						0x1000
+#define CLK_CON_MUX_MUX_CLK_PERI_USI00_USI					0x1004
+#define CLK_CON_DIV_CLKCMU_OTP							0x1800
+#define CLK_CON_DIV_DIV_CLK_PERI_I2C_0						0x1804
+#define CLK_CON_DIV_DIV_CLK_PERI_I2C_1						0x1808
+#define CLK_CON_DIV_DIV_CLK_PERI_I2C_2						0x180c
+#define CLK_CON_DIV_DIV_CLK_PERI_I2C_3						0x1810
+#define CLK_CON_DIV_DIV_CLK_PERI_SPI						0x1814
+#define CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C					0x1818
+#define CLK_CON_DIV_DIV_CLK_PERI_USI00_USI					0x181c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK			0x2000
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK			0x2004
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK			0x2008
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK			0x200c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK			0x2010
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK			0x2014
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK			0x2018
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK			0x201c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK			0x2020
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK			0x2024
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK			0x2028
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK				0x202c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK		0x2030
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK			0x2034
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK		0x2038
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0		0x203c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK	0x2040
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK	0x2044
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK	0x2048
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK	0x204c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK	0x2050
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK	0x2054
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK	0x2058
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK	0x205c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK	0x2060
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK	0x2064
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK		0x2068
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK			0x206c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK			0x2070
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK			0x2074
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK			0x2078
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK			0x207c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK			0x2080
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK			0x2084
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK			0x2088
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK			0x208c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK			0x2090
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK			0x2094
+#define CLK_CON_GAT_GATE_CLK_PERI_I2C_0						0x2098
+#define CLK_CON_GAT_GATE_CLK_PERI_I2C_1						0x209c
+#define CLK_CON_GAT_GATE_CLK_PERI_I2C_2						0x20a0
+#define CLK_CON_GAT_GATE_CLK_PERI_I2C_3						0x20a4
+#define CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C					0x20a8
+
+static const unsigned long peri_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
+	PLL_CON1_MUX_CLKCMU_PERI_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_PERI_IP_USER,
+	PLL_CON1_MUX_CLKCMU_PERI_IP_USER,
+	PLL_CON0_MUX_CLKCMU_PERI_UART_USER,
+	PLL_CON1_MUX_CLKCMU_PERI_UART_USER,
+	PERI_CMU_PERI_CONTROLLER_OPTION,
+	CLK_CON_MUX_MUX_CLK_PERI_SPI,
+	CLK_CON_MUX_MUX_CLK_PERI_USI00_USI,
+	CLK_CON_DIV_CLKCMU_OTP,
+	CLK_CON_DIV_DIV_CLK_PERI_I2C_0,
+	CLK_CON_DIV_DIV_CLK_PERI_I2C_1,
+	CLK_CON_DIV_DIV_CLK_PERI_I2C_2,
+	CLK_CON_DIV_DIV_CLK_PERI_I2C_3,
+	CLK_CON_DIV_DIV_CLK_PERI_SPI,
+	CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C,
+	CLK_CON_DIV_DIV_CLK_PERI_USI00_USI,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GATE_CLK_PERI_I2C_0,
+	CLK_CON_GAT_GATE_CLK_PERI_I2C_1,
+	CLK_CON_GAT_GATE_CLK_PERI_I2C_2,
+	CLK_CON_GAT_GATE_CLK_PERI_I2C_3,
+	CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C,
+};
+
+/* Parent clock list for CMU_PERI muxes */
+PNAME(mout_pll_peri_bus_user_p)		= { "oscclk",
+					    "mout_cmu_peri_bus" };
+
+PNAME(mout_pll_peri_ip_user_p)		= { "oscclk",
+					    "mout_cmu_peri_ip" };
+
+/* Parent clock list for CMU_PERI muxes: for SPI */
+PNAME(mout_peri_spi_p)			= { "oscclk",
+					    "mout_pll_peri_ip_user" };
+
+/* Parent clock list for CMU_PERI muxes: for UART */
+PNAME(mout_pll_peri_uart_user_p)	= { "oscclk",
+					    "mout_cmu_peri_uart" };
+
+/* Parent clock list for CMU_PERI muxes: for USI */
+PNAME(mout_peri_usi00_usi_p)		= { "oscclk",
+					    "mout_pll_peri_ip_user" };
+
+static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
+	/* BUS */
+	MUX(CLK_MOUT_PLL_PERI_BUS_USER, "mout_pll_peri_bus_user",
+	    mout_pll_peri_bus_user_p,
+	    PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
+	    4, 1),
+
+	/* IP */
+	MUX(CLK_MOUT_PLL_PERI_IP_USER, "mout_pll_peri_ip_user",
+	    mout_pll_peri_ip_user_p,
+	    PLL_CON0_MUX_CLKCMU_PERI_IP_USER,
+	    4, 1),
+
+	/* SPI */
+	MUX(CLK_MOUT_PERI_SPI, "mout_peri_spi",
+	    mout_peri_spi_p,
+	    CLK_CON_MUX_MUX_CLK_PERI_SPI,
+	    0, 1),
+
+	/* UART */
+	MUX(CLK_MOUT_PLL_PERI_UART_USER, "mout_pll_peri_uart_user",
+	    mout_pll_peri_uart_user_p,
+	    PLL_CON0_MUX_CLKCMU_PERI_UART_USER,
+	    4, 1),
+
+	/* USI (Universal Serial Interface) */
+	MUX(CLK_MOUT_PERI_USI00_USI, "mout_peri_usi00_usi",
+	    mout_peri_usi00_usi_p,
+	    CLK_CON_MUX_MUX_CLK_PERI_USI00_USI,
+	    0, 1),
+};
+
+static const struct samsung_div_clock peri_div_clks[] __initconst = {
+	/* I2C */
+	DIV(CLK_DOUT_PERI_I2C_0, "dout_peri_i2c_0",
+	    "gout_peri_i2c_0",
+	    CLK_CON_DIV_DIV_CLK_PERI_I2C_0,
+	    0, 4),
+	DIV(CLK_DOUT_PERI_I2C_1, "dout_peri_i2c_1",
+	    "gout_peri_i2c_1",
+	    CLK_CON_DIV_DIV_CLK_PERI_I2C_1,
+	    0, 4),
+	DIV(CLK_DOUT_PERI_I2C_2, "dout_peri_i2c_2",
+	    "gout_peri_i2c_2",
+	    CLK_CON_DIV_DIV_CLK_PERI_I2C_2,
+	    0, 4),
+	DIV(CLK_DOUT_PERI_I2C_3, "dout_peri_i2c_3",
+	    "gout_peri_i2c_3",
+	    CLK_CON_DIV_DIV_CLK_PERI_I2C_3,
+	    0, 4),
+
+	/* SPI */
+	DIV(CLK_DOUT_PERI_SPI, "dout_peri_spi",
+	    "mout_peri_spi",
+	    CLK_CON_DIV_DIV_CLK_PERI_SPI,
+	    0, 5),
+
+	/* USI */
+	DIV(CLK_DOUT_PERI_USI00_I2C, "dout_peri_usi00_i2c",
+	    "gout_peri_usi00_i2c",
+	    CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C,
+	    0, 4),
+	DIV(CLK_DOUT_PERI_USI00_USI, "dout_peri_usi00_usi",
+	    "mout_peri_usi00_usi",
+	    CLK_CON_DIV_DIV_CLK_PERI_USI00_USI,
+	    0, 5),
+};
+
+static const struct samsung_fixed_factor_clock peri_fixed_factor_clks[] __initconst = {
+	/* OTP (One-Time Programmable eFuses) */
+	FFACTOR(CLK_DOUT_PERI_OTP, "dout_peri_otp", "oscclk",
+		1, 8, 0),
+};
+
+static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
+	/* BUS */
+	GATE(CLK_GOUT_PERI_BUSIF_TMU_PCLK, "gout_peri_busif_tmu_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_BUS_CLK, "gout_peri_bus_clk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* CMU */
+	GATE(CLK_GOUT_PERI_CMU_PCLK, "gout_peri_cmu_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* GPIO */
+	GATE(CLK_GOUT_PERI_GPIO_PCLK, "gout_peri_gpio_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* I2C */
+	GATE(CLK_GOUT_PERI_I2C_0_IPCLK, "gout_peri_i2c_0_ipclk",
+	     "dout_peri_i2c_0",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_0_PCLK, "gout_peri_i2c_0_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_1_IPCLK, "gout_peri_i2c_1_ipclk",
+	     "dout_peri_i2c_1",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_1_PCLK, "gout_peri_i2c_1_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_2_IPCLK, "gout_peri_i2c_2_ipclk",
+	     "dout_peri_i2c_2",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_2_PCLK, "gout_peri_i2c_2_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_3_IPCLK, "gout_peri_i2c_3_ipclk",
+	     "dout_peri_i2c_3",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_3_PCLK, "gout_peri_i2c_3_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_0_CLK, "gout_peri_i2c_0_clk",
+	     "dout_peri_i2c_0",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_1_CLK, "gout_peri_i2c_1_clk",
+	     "dout_peri_i2c_1",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_2_CLK, "gout_peri_i2c_2_clk",
+	     "dout_peri_i2c_2",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_3_CLK, "gout_peri_i2c_3_clk",
+	     "dout_peri_i2c_3",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_0, "gout_peri_i2c_0",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_I2C_0,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_1, "gout_peri_i2c_1",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_I2C_1,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_2, "gout_peri_i2c_2",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_I2C_2,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_3, "gout_peri_i2c_3",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_I2C_3,
+	     21, 0, 0),
+
+	/* MCT (Multi-Core Timer) */
+	GATE(CLK_GOUT_PERI_MCT_PCLK, "gout_peri_mct_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* OTP */
+	GATE(CLK_GOUT_PERI_OTP_OSCCLK, "gout_peri_otp_oscclk",
+	     "oscclk",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_OTP_PCLK, "gout_peri_otp_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* OSCCLK */
+	GATE(CLK_GOUT_PERI_OSCCLK, "gout_peri_oscclk",
+	     "oscclk",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* PWM */
+	GATE(CLK_GOUT_PERI_PWM_MOTOR_PCLK, "gout_peri_pwm_motor_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0,
+	     21, 0, 0),
+
+	/* SPI */
+	GATE(CLK_GOUT_PERI_SPI_CLK, "gout_peri_spi_clk",
+	     "dout_peri_spi",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* SYSREG */
+	GATE(CLK_GOUT_PERI_SYSREG_PCLK, "gout_peri_sysreg_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* TZ */
+	GATE(CLK_GOUT_PERI_D_TZPC_PCLK, "gout_peri_d_tzpc_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* UART */
+	GATE(CLK_GOUT_PERI_UART_CLK, "gout_peri_uart_clk",
+	     "mout_pll_peri_uart_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* USI */
+	GATE(CLK_GOUT_PERI_USI00_I2C_CLK, "gout_peri_usi00_i2c_clk",
+	     "dout_peri_usi00_i2c",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_USI_CLK, "gout_peri_usi00_usi_clk",
+	     "dout_peri_usi00_usi",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_I2C_IPCLK, "gout_peri_usi00_i2c_ipclk",
+	     "dout_peri_usi00_i2c",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_I2C_PCLK, "gout_peri_usi00_i2c_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_USI_IPCLK, "gout_peri_usi00_usi_ipclk",
+	     "dout_peri_usi00_usi",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_USI_PCLK, "gout_peri_usi00_usi_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI_SPI_IPCLK, "gout_peri_usi_spi_ipclk",
+	     "dout_peri_spi",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI_SPI_PCLK, "gout_peri_usi_spi_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI_UART_IPCLK, "gout_peri_usi_uart_ipclk",
+	     "mout_pll_peri_uart_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI_UART_PCLK, "gout_peri_usi_uart_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_I2C, "gout_peri_usi00_i2c",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C,
+	     21, 0, 0),
+
+	/* WDT (Watchdog Timer) */
+	GATE(CLK_GOUT_PERI_WDT0_PCLK, "gout_peri_wdt0_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_WDT1_PCLK, "gout_peri_wdt1_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* UNKNOWN */
+	GATE(CLK_GOUT_PERI_SLH_AXI_MI_P_CLK, "gout_peri_slh_axi_mi_p_clk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK,
+	     21, 0, 0),
+};
+
+static const struct samsung_cmu_info peri_cmu_info __initconst = {
+	.mux_clks		= peri_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(peri_mux_clks),
+	.div_clks		= peri_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(peri_div_clks),
+	.fixed_factor_clks	= peri_fixed_factor_clks,
+	.nr_fixed_factor_clks	= ARRAY_SIZE(peri_fixed_factor_clks),
+	.gate_clks		= peri_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(peri_gate_clks),
+	.nr_clk_ids		= CLKS_NR_PERI,
+	.clk_regs		= peri_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(peri_clk_regs),
+	.sysreg_clk_regs	= drcg_sysreg,
+	.nr_sysreg_clk_regs	= ARRAY_SIZE(drcg_sysreg),
+	.clk_name		= "bus",
+	.auto_clock_gate	= true,
+	.gate_dbg_offset	= EXYNOS5515_GATE_DBG_OFFSET,
+	.option_offset		= PERI_CMU_PERI_CONTROLLER_OPTION,
+	.drcg_offset		= EXYNOS5515_DRCG_EN_OFFSET,
+};
+
+static void __init exynos5515_cmu_peri_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &peri_cmu_info);
+}
+
+/* Register CMU_PERI early, as it's a dependency for the MCT. */
+CLK_OF_DECLARE(exynos5515_cmu_peri, "samsung,exynos5515-cmu-peri",
+	       exynos5515_cmu_peri_init);
+
+/* ---- CMU_FSYS ------------------------------------------------------------ */
+
+/*
+ * CMU_FSYS:	0x10400000
+ * SYSREG_FSYS:	0x10420000
+ */
+
+#define PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER						0x0600
+#define PLL_CON1_MUX_CLKCMU_FSYS_BUS_USER						0x0604
+#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER						0x0610
+#define PLL_CON1_MUX_CLKCMU_FSYS_MMC_CARD_USER						0x0614
+#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER						0x0620
+#define PLL_CON1_MUX_CLKCMU_FSYS_MMC_EMBD_USER						0x0624
+#define PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER						0x0630
+#define PLL_CON1_MUX_CLKCMU_FSYS_USB20DRD_USER						0x0634
+#define FSYS_CMU_FSYS_CONTROLLER_OPTION							0x0800
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK			0x2000
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN				0x2004
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN				0x2008
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK		0x200c
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50	0x2010
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26	0x2014
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK			0x2018
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK				0x201c
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK				0x2020
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK				0x2024
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK				0x2028
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK				0x202c
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK		0x2030
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK			0x2034
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK			0x2038
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK			0x203c
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20		0x2040
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY		0x2044
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK			0x2048
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK				0x204c
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK				0x2050
+
+static const unsigned long fsys_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER,
+	PLL_CON1_MUX_CLKCMU_FSYS_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER,
+	PLL_CON1_MUX_CLKCMU_FSYS_MMC_CARD_USER,
+	PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER,
+	PLL_CON1_MUX_CLKCMU_FSYS_MMC_EMBD_USER,
+	PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER,
+	PLL_CON1_MUX_CLKCMU_FSYS_USB20DRD_USER,
+	FSYS_CMU_FSYS_CONTROLLER_OPTION,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK,
+};
+
+/* Parent clock list for CMU_FSYS muxes */
+PNAME(mout_pll_fsys_bus_user_p)		= { "dout_cmu_fsys_bus",
+					    "oscclk" };
+
+/* Parent clock list for CMU_FSYS muxes: for MMC */
+PNAME(mout_pll_fsys_mmc_card_user_p)	= { "dout_cmu_fsys_mmc_card",
+					    "oscclk" };
+
+PNAME(mout_pll_fsys_mmc_embd_user_p)	= { "dout_cmu_fsys_mmc_embd",
+					    "oscclk" };
+
+/* Parent clock list for CMU_FSYS muxes: for USB */
+PNAME(mout_pll_fsys_usb20drd_user_p)	= { "dout_cmu_fsys_usb20drd",
+					    "oscclk" };
+
+static const struct samsung_mux_clock fsys_mux_clks[] __initconst = {
+	/* BUS */
+	MUX(CLK_MOUT_PLL_FSYS_BUS_USER, "mout_pll_fsys_bus_user",
+	    mout_pll_fsys_bus_user_p,
+	    PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER,
+	    4, 1),
+
+	/* MMC */
+	MUX(CLK_MOUT_PLL_FSYS_MMC_CARD_USER, "mout_pll_fsys_mmc_card_user",
+	    mout_pll_fsys_mmc_card_user_p,
+	    PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER,
+	    4, 1),
+	MUX(CLK_MOUT_PLL_FSYS_MMC_EMBD_USER, "mout_pll_fsys_mmc_embd_user",
+	    mout_pll_fsys_mmc_embd_user_p,
+	    PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER,
+	    4, 1),
+
+	/* USB */
+	MUX(CLK_MOUT_PLL_FSYS_USB20DRD_USER, "mout_pll_fsys_usb20drd_user",
+	    mout_pll_fsys_usb20drd_user_p,
+	    PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER,
+	    4, 1),
+};
+
+static const struct samsung_gate_clock fsys_gate_clks[] __initconst = {
+	/* BUS */
+	GATE(CLK_GOUT_FSYS_BUS_CLK, "gout_fsys_bus_clk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* CMU */
+	GATE(CLK_GOUT_FSYS_CMU_PCLK, "gout_fsys_cmu_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* GPIO */
+	GATE(CLK_GOUT_FSYS_GPIO_PCLK, "gout_fsys_gpio_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* MMC */
+	GATE(CLK_GOUT_FSYS_MMC_CARD_SDCLKIN, "gout_fsys_mmc_card_sdclkin",
+	     "mout_pll_fsys_mmc_card_user",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_MMC_EMBD_SDCLKIN, "gout_fsys_mmc_embd_sdclkin",
+	     "mout_pll_fsys_mmc_embd_user",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_MMC_CARD_ACLK, "gout_fsys_mmc_card_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_MMC_EMBD_ACLK, "gout_fsys_mmc_embd_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK,
+	     21, 0, 0),
+
+	/* OSCCLK */
+	GATE(CLK_GOUT_FSYS_OSCCLK, "gout_fsys_oscclk",
+	     "oscclk",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* PMU */
+	GATE(CLK_GOUT_FSYS_PPMU_ACLK, "gout_fsys_ppmu_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_PPMU_PCLK, "gout_fsys_ppmu_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* SYSREG */
+	GATE(CLK_GOUT_FSYS_SYSREG_PCLK, "gout_fsys_sysreg_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* TZ */
+	GATE(CLK_GOUT_FSYS_D_TZPC_PCLK, "gout_fsys_d_tzpc_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* USB */
+	GATE(CLK_GOUT_FSYS_USB20DRD_REFCLK,
+	     "gout_fsys_usb20drd_refclk",
+	     "mout_pll_fsys_usb20drd_user",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_USB20DRD_PHY_REFCLK,
+	     "gout_fsys_usb20drd_phy_refclk",
+	     "oscclk",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_USB20DRD_ACLK_PHYCTRL,
+	     "gout_fsys_usb20drd_aclk_phyctrl",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_USB20DRD_BUS_CLK_EARLY,
+	     "gout_fsys_usb20drd_bus_clk_early",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY,
+	     21, 0, 0),
+
+	/* UNKNOWN */
+	GATE(CLK_GOUT_FSYS_SLH_AXI_MI_P_CLK, "gout_fsys_slh_axi_mi_p_clk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_SLH_AXI_SI_D_CLK, "gout_fsys_slh_axi_si_d_clk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_US_64TO128_ACLK, "gout_fsys_us_64to128_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_XIU_D_ACLK, "gout_fsys_xiu_d_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_XIU_P_ACLK, "gout_fsys_xiu_p_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK,
+	     21, 0, 0),
+};
+
+static const struct samsung_cmu_info fsys_cmu_info __initconst = {
+	.mux_clks		= fsys_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys_mux_clks),
+	.gate_clks		= fsys_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys_gate_clks),
+	.nr_clk_ids		= CLKS_NR_FSYS,
+	.clk_regs		= fsys_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys_clk_regs),
+	.sysreg_clk_regs	= drcg_sysreg,
+	.nr_sysreg_clk_regs	= ARRAY_SIZE(drcg_sysreg),
+	.clk_name		= "bus",
+	.auto_clock_gate	= true,
+	.gate_dbg_offset	= EXYNOS5515_GATE_DBG_OFFSET,
+	.option_offset		= FSYS_CMU_FSYS_CONTROLLER_OPTION,
+	.drcg_offset		= EXYNOS5515_DRCG_EN_OFFSET,
+};
+
+/* ----- platform_driver ----- */
+
+static int __init exynos5515_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+static const struct of_device_id exynos5515_cmu_of_match[] = {
+	{
+		.compatible = "samsung,exynos5515-cmu-fsys",
+		.data = &fsys_cmu_info,
+	},
+	{ },
+};
+
+static struct platform_driver exynos5515_cmu_driver __refdata = {
+	.driver = {
+		.name = "exynos5515-cmu",
+		.of_match_table = exynos5515_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = exynos5515_cmu_probe,
+};
+
+static int __init exynos5515_cmu_init(void)
+{
+	return platform_driver_register(&exynos5515_cmu_driver);
+}
+
+core_initcall(exynos5515_cmu_init);

-- 
2.54.0



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

* [PATCH 3/3] clk: samsung: Introduce Exynos5515 clock driver
@ 2026-08-17 10:17   ` Aiden Isik
  0 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik @ 2026-08-17 10:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
	Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
	Brian Masney, Rob Herring, Conor Dooley, Kees Cook,
	Gustavo A. R. Silva
  Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
	linux-kernel, linux-hardening, Aiden Isik

CMU_TOP is the top level clock management unit which contains PLLs,
muxes, dividers and gates that feed the other clock management units.

CMU_PERI provides clocks for USI blocks and their children, PWM, MCT,
and watchdog timers.

CMU_FSYS provides clocks for MMC, USB, GPIO, etc.

More blocks will be added as device drivers which utilise them are added.

Signed-off-by: Aiden Isik <aidenisik+git@member.fsf.org>
---
 drivers/clk/samsung/Makefile         |    1 +
 drivers/clk/samsung/clk-exynos5515.c | 1485 ++++++++++++++++++++++++++++++++++
 2 files changed, 1486 insertions(+)

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index b3c4ef4e0dbf..b3e994bd525d 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
 obj-$(CONFIG_EXYNOS_CLKOUT)	+= clk-exynos-clkout.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos-arm64.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos2200.o
+obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos5515.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7870.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7885.o
diff --git a/drivers/clk/samsung/clk-exynos5515.c b/drivers/clk/samsung/clk-exynos5515.c
new file mode 100644
index 000000000000..f989a13f1a57
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos5515.c
@@ -0,0 +1,1485 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Aiden Isik <aidenisik+git@member.fsf.org>
+ * Author: Aiden Isik <aidenisik+git@member.fsf.org>
+ *
+ * Common Clock Framework support for Exynos5515 SoC.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/samsung,exynos5515-cmu.h>
+
+#include "clk.h"
+#include "clk-exynos-arm64.h"
+#include "clk-pll.h"
+
+/* NOTE: Must be equal to the last clock ID increased by one */
+#define CLKS_NR_TOP	(CLK_GOUT_CMU_PERI_UART + 1)
+#define CLKS_NR_PERI	(CLK_GOUT_PERI_USI00_I2C + 1)
+#define CLKS_NR_FSYS	(CLK_GOUT_FSYS_XIU_P_ACLK + 1)
+
+#define EXYNOS5515_GATE_DBG_OFFSET	0x4000
+#define EXYNOS5515_DRCG_EN_OFFSET	0x0104
+#define EXYNOS5515_MEMCLK_OFFSET	0x0108
+
+/* ---- CMU_TOP ------------------------------------------------------------- */
+
+/*
+ * CMU_TOP:	0x15410000
+ * SYSREG_TOP:	0x15430000
+ */
+
+/* Register Offset definitions for CMU_TOP */
+#define PLL_LOCKTIME_PLL_AUD			0x0000
+#define PLL_LOCKTIME_PLL_SHARED0		0x0004
+#define PLL_LOCKTIME_PLL_SHARED1		0x0008
+#define PLL_CON3_PLL_AUD			0x010c
+#define PLL_CON8_PLL_AUD			0x0120
+#define PLL_CON9_PLL_AUD			0x0124
+#define PLL_CON3_PLL_SHARED0			0x014c
+#define PLL_CON8_PLL_SHARED0			0x0160
+#define PLL_CON9_PLL_SHARED0			0x0164
+#define PLL_CON3_PLL_SHARED1			0x018c
+#define PLL_CON8_PLL_SHARED1			0x01a0
+#define PLL_CON9_PLL_SHARED1			0x01a4
+#define CMU_CMU_TOP_CONTROLLER_OPTION		0x0800
+#define CLK_CON_MUX_MUX_CLKCMU_APM_BUS		0x1000
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS		0x1004
+#define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS		0x1008
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP	0x100c
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU	0x1010
+#define CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG	0x1014
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF	0x1018
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS	0x101c
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU	0x1020
+#define CLK_CON_MUX_MUX_CLKCMU_DPU_BUS		0x1024
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS		0x1028
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD	0x102c
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD	0x1030
+#define CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD	0x1034
+#define CLK_CON_MUX_MUX_CLKCMU_G3D_BUS		0x1038
+#define CLK_CON_MUX_MUX_CLKCMU_MFC_BUS		0x103c
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP		0x1040
+#define CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH	0x1044
+#define CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1	0x1048
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS		0x104c
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_IP		0x1050
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART	0x1054
+#define CLK_CON_MUX_MUX_CMU_CMUREF		0x1058
+#define CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK	0x1800
+#define CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK	0x1804
+#define CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK	0x1808
+#define CLK_CON_DIV_CLKCMU_APM_BUS		0x180c
+#define CLK_CON_DIV_CLKCMU_CMU_BOOST		0x1810
+#define CLK_CON_DIV_CLKCMU_CORE_BUS		0x1814
+#define CLK_CON_DIV_CLKCMU_CORE_SSS		0x1818
+#define CLK_CON_DIV_CLKCMU_CPUCL0_BUSP		0x181c
+#define CLK_CON_DIV_CLKCMU_CPUCL0_CPU		0x1820
+#define CLK_CON_DIV_CLKCMU_CPUCL0_DBG		0x1824
+#define CLK_CON_DIV_CLKCMU_DPU_AUDIF		0x1828
+#define CLK_CON_DIV_CLKCMU_DPU_AUD_BUS		0x182c
+#define CLK_CON_DIV_CLKCMU_DPU_AUD_CPU		0x1830
+#define CLK_CON_DIV_CLKCMU_DPU_BUS		0x1834
+#define CLK_CON_DIV_CLKCMU_FSYS_BUS		0x1838
+#define CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD	0x183c
+#define CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD	0x1840
+#define CLK_CON_DIV_CLKCMU_FSYS_USB20DRD	0x1844
+#define CLK_CON_DIV_CLKCMU_G3D_BUS		0x1848
+#define CLK_CON_DIV_CLKCMU_MFC_BUS		0x184c
+#define CLK_CON_DIV_CLKCMU_MIF_BUSP		0x1850
+#define CLK_CON_DIV_CLKCMU_PERI_BUS		0x1854
+#define CLK_CON_DIV_CLKCMU_PERI_IP		0x1858
+#define CLK_CON_DIV_CLKCMU_PERI_UART		0x185c
+#define CLK_CON_DIV_DIV_CLK_CMU_CMUREF		0x1860
+#define CLK_CON_GAT_CLKCMU_MIF_SWITCH		0x2030
+#define CLK_CON_GAT_GATE_CLKCMU_APM_BUS		0x2034
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS	0x2038
+#define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS	0x203c
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP	0x2040
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU	0x2044
+#define CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG	0x2048
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF	0x204c
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS	0x2050
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU	0x2054
+#define CLK_CON_GAT_GATE_CLKCMU_DPU_BUS		0x2058
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS	0x205c
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD	0x2060
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD	0x2064
+#define CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD	0x2068
+#define CLK_CON_GAT_GATE_CLKCMU_G3D_BUS		0x206c
+#define CLK_CON_GAT_GATE_CLKCMU_MFC_BUS		0x2070
+#define CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP	0x2074
+#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0	0x2078
+#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1	0x207c
+#define CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2	0x2080
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS	0x2084
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_IP		0x2088
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART	0x208c
+
+static const unsigned long top_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_AUD,
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_CON3_PLL_AUD,
+	PLL_CON8_PLL_AUD,
+	PLL_CON9_PLL_AUD,
+	PLL_CON3_PLL_SHARED0,
+	PLL_CON8_PLL_SHARED0,
+	PLL_CON9_PLL_SHARED0,
+	PLL_CON3_PLL_SHARED1,
+	PLL_CON8_PLL_SHARED1,
+	PLL_CON9_PLL_SHARED1,
+	CMU_CMU_TOP_CONTROLLER_OPTION,
+	CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU,
+	CLK_CON_MUX_MUX_CLKCMU_DPU_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD,
+	CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD,
+	CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD,
+	CLK_CON_MUX_MUX_CLKCMU_G3D_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MFC_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP,
+	CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH,
+	CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1,
+	CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
+	CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
+	CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
+	CLK_CON_MUX_MUX_CMU_CMUREF,
+	CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK,
+	CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK,
+	CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK,
+	CLK_CON_DIV_CLKCMU_APM_BUS,
+	CLK_CON_DIV_CLKCMU_CMU_BOOST,
+	CLK_CON_DIV_CLKCMU_CORE_BUS,
+	CLK_CON_DIV_CLKCMU_CORE_SSS,
+	CLK_CON_DIV_CLKCMU_CPUCL0_BUSP,
+	CLK_CON_DIV_CLKCMU_CPUCL0_CPU,
+	CLK_CON_DIV_CLKCMU_CPUCL0_DBG,
+	CLK_CON_DIV_CLKCMU_DPU_AUDIF,
+	CLK_CON_DIV_CLKCMU_DPU_AUD_BUS,
+	CLK_CON_DIV_CLKCMU_DPU_AUD_CPU,
+	CLK_CON_DIV_CLKCMU_DPU_BUS,
+	CLK_CON_DIV_CLKCMU_FSYS_BUS,
+	CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD,
+	CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD,
+	CLK_CON_DIV_CLKCMU_FSYS_USB20DRD,
+	CLK_CON_DIV_CLKCMU_G3D_BUS,
+	CLK_CON_DIV_CLKCMU_MFC_BUS,
+	CLK_CON_DIV_CLKCMU_MIF_BUSP,
+	CLK_CON_DIV_CLKCMU_PERI_BUS,
+	CLK_CON_DIV_CLKCMU_PERI_IP,
+	CLK_CON_DIV_CLKCMU_PERI_UART,
+	CLK_CON_DIV_DIV_CLK_CMU_CMUREF,
+	CLK_CON_GAT_CLKCMU_MIF_SWITCH,
+	CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU,
+	CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU,
+	CLK_CON_GAT_GATE_CLKCMU_DPU_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD,
+	CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD,
+	CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD,
+	CLK_CON_GAT_GATE_CLKCMU_G3D_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MFC_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP,
+	CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0,
+	CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1,
+	CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2,
+	CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
+	CLK_CON_GAT_GATE_CLKCMU_PERI_IP,
+	CLK_CON_GAT_GATE_CLKCMU_PERI_UART,
+};
+
+static const struct samsung_pll_clock top_pll_clks[] __initconst = {
+	PLL(pll_309, CLK_FOUT_AUD_PLL, "fout_aud_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_AUD, PLL_CON3_PLL_AUD, NULL),
+	PLL(pll_309, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL),
+	PLL(pll_309, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
+	    PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL),
+};
+
+/* Parent clock list for CMU_TOP muxes */
+PNAME(mout_cmu_cmuref_p)	= { "dout_cmu_cmuref",
+				    "oscclk" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_APM */
+PNAME(mout_cmu_apm_bus_p)	= { "dout_shared0_div2",
+				    "dout_shared0_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_CORE */
+PNAME(mout_cmu_core_bus_p)	= { "dout_aud_div3",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div3" };
+
+PNAME(mout_cmu_core_sss_p)	= { "dout_aud_div3",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_CPUCL0 */
+PNAME(mout_cmu_cpucl0_busp_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+PNAME(mout_cmu_cpucl0_cpu_p)	= { "dout_aud_div2",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3",
+				    "dout_shared1_div4",
+				    "fout_aud_pll" };
+
+PNAME(mout_cmu_cpucl0_dbg_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_DPU */
+PNAME(mout_cmu_dpu_audif_p)	= { "dout_aud_div2",
+				    "dout_aud_div3" };
+
+PNAME(mout_cmu_dpu_aud_bus_p)	= { "dout_aud_div2",
+				    "dout_aud_div3",
+				    "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+PNAME(mout_cmu_dpu_aud_cpu_p)	= { "dout_aud_div2",
+				    "dout_aud_div3",
+				    "dout_aud_div4",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3",
+				    "fout_aud_pll" };
+
+PNAME(mout_cmu_dpu_bus_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_FSYS */
+PNAME(mout_cmu_fsys_bus_p)	= { "dout_shared0_div2",
+				    "dout_shared1_div3" };
+
+PNAME(mout_cmu_fsys_mmc_card_p)	= { "dout_aud_div2",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div3",
+				    "oscclk" };
+
+PNAME(mout_cmu_fsys_mmc_embd_p)	= { "dout_aud_div2",
+				    "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div3",
+				    "oscclk" };
+
+PNAME(mout_cmu_fsys_usb20drd_p)	= { "dout_shared0_div4",
+				    "oscclk" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_G3D */
+PNAME(mout_cmu_g3d_bus_p)	= { "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_MFC */
+PNAME(mout_cmu_mfc_bus_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div3",
+				    "dout_shared1_div4" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_MIF */
+PNAME(mout_cmu_mif_busp_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+PNAME(mout_cmu_mif_switch_p)	= { "dout_shared0_div2",
+				    "dout_shared0_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3",
+				    "dout_shared1_div4",
+				    "fout_shared0_pll",
+				    "fout_shared1_pll" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_MODEM */
+PNAME(mout_cmu_modem_shared1_p)	= { "dout_aud_div2",
+				    "dout_shared0_div3",
+				    "dout_shared1_div2",
+				    "dout_shared1_div3" };
+
+/* Parent clock list for CMU_TOP muxes: for CMU_PERI */
+PNAME(mout_cmu_peri_bus_p)	= { "dout_shared0_div3",
+				    "dout_shared0_div4" };
+
+PNAME(mout_cmu_peri_ip_p)	= { "dout_aud_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div4",
+				    "oscclk" };
+
+PNAME(mout_cmu_peri_uart_p)	= { "dout_aud_div3",
+				    "dout_shared0_div4",
+				    "dout_shared1_div4",
+				    "oscclk" };
+
+static const struct samsung_mux_clock top_mux_clks[] __initconst = {
+	/* APM (Active Power Management) */
+	MUX(CLK_MOUT_CMU_APM_BUS, "mout_cmu_apm_bus",
+	    mout_cmu_apm_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_APM_BUS,
+	    0, 1),
+
+	/* CMU (Clock Management Unit) */
+	MUX(CLK_MOUT_CMU_CMUREF, "mout_cmu_cmuref",
+	    mout_cmu_cmuref_p,
+	    CLK_CON_MUX_MUX_CMU_CMUREF,
+	    0, 1),
+
+	/* CORE */
+	MUX(CLK_MOUT_CMU_CORE_BUS, "mout_cmu_core_bus",
+	    mout_cmu_core_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_CORE_SSS, "mout_cmu_core_sss",
+	    mout_cmu_core_sss_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
+	    0, 2),
+
+	/* CPUCL0 (CPU Cluster 0) */
+	MUX(CLK_MOUT_CMU_CPUCL0_BUSP, "mout_cmu_cpucl0_busp",
+	    mout_cmu_cpucl0_busp_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_BUSP,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_CPUCL0_CPU, "mout_cmu_cpucl0_cpu",
+	    mout_cmu_cpucl0_cpu_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_CPU,
+	    0, 3),
+	MUX(CLK_MOUT_CMU_CPUCL0_DBG, "mout_cmu_cpucl0_dbg",
+	    mout_cmu_cpucl0_dbg_p,
+	    CLK_CON_MUX_MUX_CLKCMU_CPUCL0_DBG,
+	    0, 1),
+
+	/* DPU (Display Processing Unit) */
+	MUX(CLK_MOUT_CMU_DPU_AUDIF, "mout_cmu_dpu_audif",
+	    mout_cmu_dpu_audif_p,
+	    CLK_CON_MUX_MUX_CLKCMU_DPU_AUDIF,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_DPU_AUD_BUS, "mout_cmu_dpu_aud_bus",
+	    mout_cmu_dpu_aud_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_BUS,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_DPU_AUD_CPU, "mout_cmu_dpu_aud_cpu",
+	    mout_cmu_dpu_aud_cpu_p,
+	    CLK_CON_MUX_MUX_CLKCMU_DPU_AUD_CPU,
+	    0, 3),
+	MUX(CLK_MOUT_CMU_DPU_BUS, "mout_cmu_dpu_bus",
+	    mout_cmu_dpu_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_DPU_BUS,
+	    0, 2),
+
+	/* FSYS */
+	MUX(CLK_MOUT_CMU_FSYS_BUS, "mout_cmu_fsys_bus",
+	    mout_cmu_fsys_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_FSYS_BUS,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_FSYS_MMC_CARD, "mout_cmu_fsys_mmc_card",
+	    mout_cmu_fsys_mmc_card_p,
+	    CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_CARD,
+	    0, 3),
+	MUX(CLK_MOUT_CMU_FSYS_MMC_EMBD, "mout_cmu_fsys_mmc_embd",
+	    mout_cmu_fsys_mmc_embd_p,
+	    CLK_CON_MUX_MUX_CLKCMU_FSYS_MMC_EMBD,
+	    0, 3),
+	MUX(CLK_MOUT_CMU_FSYS_USB20DRD, "mout_cmu_fsys_usb20drd",
+	    mout_cmu_fsys_usb20drd_p,
+	    CLK_CON_MUX_MUX_CLKCMU_FSYS_USB20DRD,
+	    0, 1),
+
+	/* G3D */
+	MUX(CLK_MOUT_CMU_G3D_BUS, "mout_cmu_g3d_bus",
+	    mout_cmu_g3d_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_G3D_BUS,
+	    0, 2),
+
+	/* MFC */
+	MUX(CLK_MOUT_CMU_MFC_BUS, "mout_cmu_mfc_bus",
+	    mout_cmu_mfc_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_MFC_BUS,
+	    0, 2),
+
+	/* MIF */
+	MUX(CLK_MOUT_CMU_MIF_BUSP, "mout_cmu_mif_busp",
+	    mout_cmu_mif_busp_p,
+	    CLK_CON_MUX_MUX_CLKCMU_MIF_BUSP,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_MIF_SWITCH, "mout_cmu_mif_switch",
+	    mout_cmu_mif_switch_p,
+	    CLK_CON_MUX_MUX_CLKCMU_MIF_SWITCH,
+	    0, 3),
+
+	/* MODEM */
+	MUX(CLK_MOUT_CMU_MODEM_SHARED1, "mout_cmu_modem_shared1",
+	    mout_cmu_modem_shared1_p,
+	    CLK_CON_MUX_MUX_CLKCMU_MODEM_SHARED1,
+	    0, 2),
+
+	/* PERI */
+	MUX(CLK_MOUT_CMU_PERI_BUS, "mout_cmu_peri_bus",
+	    mout_cmu_peri_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
+	    0, 1),
+	MUX(CLK_MOUT_CMU_PERI_IP, "mout_cmu_peri_ip",
+	    mout_cmu_peri_ip_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
+	    0, 2),
+	MUX(CLK_MOUT_CMU_PERI_UART, "mout_cmu_peri_uart",
+	    mout_cmu_peri_uart_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
+	    0, 2),
+};
+
+static const struct samsung_div_clock top_div_clks[] __initconst = {
+
+	/* APM */
+	DIV(CLK_DOUT_CMU_APM_BUS, "dout_cmu_apm_bus",
+	    "gout_cmu_apm_bus",
+	    CLK_CON_DIV_CLKCMU_APM_BUS,
+	    0, 3),
+
+	/* CMU */
+	DIV(CLK_DOUT_CMU_CMU_BOOST, "dout_cmu_cmu_boost",
+	    "fout_shared0_pll",
+	    CLK_CON_DIV_CLKCMU_CMU_BOOST,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CMUREF, "dout_cmu_cmuref",
+	    "fout_shared0_pll",
+	    CLK_CON_DIV_DIV_CLK_CMU_CMUREF,
+	    0, 2),
+
+	/* CORE */
+	DIV(CLK_DOUT_CMU_CORE_BUS, "dout_cmu_core_bus",
+	    "gout_cmu_core_bus",
+	    CLK_CON_DIV_CLKCMU_CORE_BUS,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_CORE_SSS, "dout_cmu_core_sss",
+	    "gout_cmu_core_sss",
+	    CLK_CON_DIV_CLKCMU_CORE_SSS,
+	    0, 4),
+
+	/* CPUCL0 */
+	DIV(CLK_DOUT_CMU_CPUCL0_BUSP, "dout_cmu_cpucl0_busp",
+	    "gout_cmu_cpucl0_busp",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_BUSP,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL0_CPU, "dout_cmu_cpucl0_cpu",
+	    "gout_cmu_cpucl0_cpu",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_CPU,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_CPUCL0_DBG, "dout_cmu_cpucl0_dbg",
+	    "gout_cmu_cpucl0_dbg",
+	    CLK_CON_DIV_CLKCMU_CPUCL0_DBG,
+	    0, 3),
+
+	/* DPU */
+	DIV(CLK_DOUT_CMU_DPU_AUDIF, "dout_cmu_dpu_audif",
+	    "gout_cmu_dpu_audif",
+	    CLK_CON_DIV_CLKCMU_DPU_AUDIF,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_DPU_AUD_BUS, "dout_cmu_dpu_aud_bus",
+	    "gout_cmu_dpu_aud_bus",
+	    CLK_CON_DIV_CLKCMU_DPU_AUD_BUS,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_DPU_AUD_CPU, "dout_cmu_dpu_aud_cpu",
+	    "gout_cmu_dpu_aud_cpu",
+	    CLK_CON_DIV_CLKCMU_DPU_AUD_CPU,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_DPU_BUS, "dout_cmu_dpu_bus",
+	    "gout_cmu_dpu_bus",
+	    CLK_CON_DIV_CLKCMU_DPU_BUS,
+	    0, 3),
+
+	/* FSYS */
+	DIV(CLK_DOUT_CMU_FSYS_BUS, "dout_cmu_fsys_bus",
+	    "gout_cmu_fsys_bus",
+	    CLK_CON_DIV_CLKCMU_FSYS_BUS,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_FSYS_MMC_CARD, "dout_cmu_fsys_mmc_card",
+	    "gout_cmu_fsys_mmc_card",
+	    CLK_CON_DIV_CLKCMU_FSYS_MMC_CARD,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_FSYS_MMC_EMBD, "dout_cmu_fsys_mmc_embd",
+	    "gout_cmu_fsys_mmc_embd",
+	    CLK_CON_DIV_CLKCMU_FSYS_MMC_EMBD,
+	    0, 9),
+	DIV(CLK_DOUT_CMU_FSYS_USB20DRD, "dout_cmu_fsys_usb20drd",
+	    "gout_cmu_fsys_usb20drd",
+	    CLK_CON_DIV_CLKCMU_FSYS_USB20DRD,
+	    0, 4),
+
+	/* G3D */
+	DIV(CLK_DOUT_CMU_G3D_BUS, "dout_cmu_g3d_bus",
+	    "gout_cmu_g3d_bus",
+	    CLK_CON_DIV_CLKCMU_G3D_BUS,
+	    0, 3),
+
+	/* MFC */
+	DIV(CLK_DOUT_CMU_MFC_BUS, "dout_cmu_mfc_bus",
+	    "gout_cmu_mfc_bus",
+	    CLK_CON_DIV_CLKCMU_MFC_BUS,
+	    0, 4),
+
+	/* MIF */
+	DIV(CLK_DOUT_CMU_MIF_BUSP, "dout_cmu_mif_busp",
+	    "gout_cmu_mif_busp",
+	    CLK_CON_DIV_CLKCMU_MIF_BUSP,
+	    0, 3),
+
+	/* PERI */
+	DIV(CLK_DOUT_CMU_PERI_BUS, "dout_cmu_peri_bus",
+	    "gout_cmu_peri_bus",
+	    CLK_CON_DIV_CLKCMU_PERI_BUS,
+	    0, 3),
+	DIV(CLK_DOUT_CMU_PERI_IP, "dout_cmu_peri_ip",
+	    "gout_cmu_peri_ip",
+	    CLK_CON_DIV_CLKCMU_PERI_IP,
+	    0, 4),
+	DIV(CLK_DOUT_CMU_PERI_UART, "dout_cmu_peri_uart",
+	    "gout_cmu_peri_uart",
+	    CLK_CON_DIV_CLKCMU_PERI_UART,
+	    0, 4),
+
+	/* SHARED */
+	DIV(CLK_DOUT_AP2CP_SHARED0_PLL, "dout_ap2cp_shared0_pll",
+	    "gout_cmu_modem_shared0",
+	    CLK_CON_DIV_AP2CP_SHARED0_PLL_CLK,
+	    0, 3),
+	DIV(CLK_DOUT_AP2CP_SHARED1_PLL, "dout_ap2cp_shared1_pll",
+	    "gout_cmu_modem_shared1",
+	    CLK_CON_DIV_AP2CP_SHARED1_PLL_CLK,
+	    0, 3),
+	DIV(CLK_DOUT_AP2CP_SHARED2_PLL, "dout_ap2cp_shared2_pll",
+	    "gout_cmu_modem_shared2",
+	    CLK_CON_DIV_AP2CP_SHARED2_PLL_CLK,
+	    0, 3),
+};
+
+static const struct samsung_fixed_factor_clock top_fixed_factor_clks[] __initconst = {
+	FFACTOR(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "fout_shared0_pll",
+		1, 2, 0),
+	FFACTOR(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll",
+		1, 3, 0),
+	FFACTOR(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll",
+		1, 4, 0),
+	FFACTOR(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "fout_shared1_pll",
+		1, 2, 0),
+	FFACTOR(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll",
+		1, 3, 0),
+	FFACTOR(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll",
+		1, 4, 0),
+	FFACTOR(CLK_DOUT_AUD_DIV2, "dout_aud_div2", "fout_aud_pll",
+		1, 2, 0),
+	FFACTOR(CLK_DOUT_AUD_DIV3, "dout_aud_div3", "fout_aud_pll",
+		1, 3, 0),
+	FFACTOR(CLK_DOUT_AUD_DIV4, "dout_aud_div4", "fout_aud_pll",
+		1, 4, 0),
+};
+
+static const struct samsung_gate_clock top_gate_clks[] __initconst = {
+	/* APM */
+	GATE(CLK_GOUT_CMU_APM_BUS, "gout_cmu_apm_bus",
+	     "mout_cmu_apm_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_APM_BUS,
+	     21, 0, 0),
+
+	/* CORE */
+	GATE(CLK_GOUT_CMU_CORE_BUS, "gout_cmu_core_bus",
+	     "mout_cmu_core_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CORE_SSS, "gout_cmu_core_sss",
+	     "mout_cmu_core_sss",
+	     CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
+	     21, 0, 0),
+
+	/* CPUCL0 */
+	GATE(CLK_GOUT_CMU_CPUCL0_BUSP, "gout_cmu_cpucl0_busp",
+	     "mout_cmu_cpucl0_busp",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_BUSP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_CPU, "gout_cmu_cpucl0_cpu",
+	     "mout_cmu_cpucl0_cpu",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_CPU,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_CPUCL0_DBG, "gout_cmu_cpucl0_dbg",
+	     "mout_cmu_cpucl0_dbg",
+	     CLK_CON_GAT_GATE_CLKCMU_CPUCL0_DBG,
+	     21, 0, 0),
+
+	/* DPU */
+	GATE(CLK_GOUT_CMU_DPU_AUDIF, "gout_cmu_dpu_audif",
+	     "mout_cmu_dpu_audif",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_AUDIF,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_AUD_BUS, "gout_cmu_dpu_aud_bus",
+	     "mout_cmu_dpu_aud_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_AUD_CPU, "gout_cmu_dpu_aud_cpu",
+	     "mout_cmu_dpu_aud_cpu",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_AUD_CPU,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_DPU_BUS, "gout_cmu_dpu_bus",
+	     "mout_cmu_dpu_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_DPU_BUS,
+	     21, 0, 0),
+
+	/* FSYS */
+	GATE(CLK_GOUT_CMU_FSYS_BUS, "gout_cmu_fsys_bus",
+	     "mout_cmu_fsys_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_FSYS_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_FSYS_MMC_CARD, "gout_cmu_fsys_mmc_card",
+	     "mout_cmu_fsys_mmc_card",
+	     CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_CARD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_FSYS_MMC_EMBD, "gout_cmu_fsys_mmc_embd",
+	     "mout_cmu_fsys_mmc_embd",
+	     CLK_CON_GAT_GATE_CLKCMU_FSYS_MMC_EMBD,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_FSYS_USB20DRD, "gout_cmu_fsys_usb20drd",
+	     "mout_cmu_fsys_usb20drd",
+	     CLK_CON_GAT_GATE_CLKCMU_FSYS_USB20DRD,
+	     21, 0, 0),
+
+	/* G3D */
+	GATE(CLK_GOUT_CMU_G3D_BUS, "gout_cmu_g3d_bus",
+	     "mout_cmu_g3d_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_G3D_BUS,
+	     21, 0, 0),
+
+	/* MFC */
+	GATE(CLK_GOUT_CMU_MFC_BUS, "gout_cmu_mfc_bus",
+	     "mout_cmu_mfc_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_MFC_BUS,
+	     21, 0, 0),
+
+	/* MIF */
+	GATE(CLK_GOUT_CMU_MIF_SWITCH, "gout_cmu_mif_switch",
+	     "mout_cmu_mif_switch",
+	     CLK_CON_GAT_CLKCMU_MIF_SWITCH,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MIF_BUSP, "gout_cmu_mif_busp",
+	     "mout_cmu_mif_busp",
+	     CLK_CON_GAT_GATE_CLKCMU_MIF_BUSP,
+	     21, 0, 0),
+
+	/* MODEM */
+	GATE(CLK_GOUT_CMU_MODEM_SHARED0, "gout_cmu_modem_shared0",
+	     "fout_shared0_pll",
+	     CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED0,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MODEM_SHARED1, "gout_cmu_modem_shared1",
+	     "mout_cmu_modem_shared1",
+	     CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED1,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_MODEM_SHARED2, "gout_cmu_modem_shared2",
+	     "fout_shared0_pll",
+	     CLK_CON_GAT_GATE_CLKCMU_MODEM_SHARED2,
+	     21, 0, 0),
+
+	/* PERI */
+	GATE(CLK_GOUT_CMU_PERI_BUS, "gout_cmu_peri_bus",
+	     "mout_cmu_peri_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERI_IP, "gout_cmu_peri_ip",
+	     "mout_cmu_peri_ip",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_IP,
+	     21, 0, 0),
+	GATE(CLK_GOUT_CMU_PERI_UART, "gout_cmu_peri_uart",
+	     "mout_cmu_peri_uart",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_UART,
+	     21, 0, 0),
+};
+
+static const unsigned long drcg_sysreg[] __initconst = {
+	EXYNOS5515_DRCG_EN_OFFSET,
+};
+
+static const struct samsung_cmu_info top_cmu_info __initconst = {
+	.pll_clks		= top_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(top_pll_clks),
+	.mux_clks		= top_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(top_mux_clks),
+	.div_clks		= top_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(top_div_clks),
+	.fixed_factor_clks	= top_fixed_factor_clks,
+	.nr_fixed_factor_clks	= ARRAY_SIZE(top_fixed_factor_clks),
+	.gate_clks		= top_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(top_gate_clks),
+	.nr_clk_ids		= CLKS_NR_TOP,
+	.clk_regs		= top_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(top_clk_regs),
+	.sysreg_clk_regs	= drcg_sysreg,
+	.nr_sysreg_clk_regs	= ARRAY_SIZE(drcg_sysreg),
+	.auto_clock_gate	= true,
+	.gate_dbg_offset	= EXYNOS5515_GATE_DBG_OFFSET,
+	.option_offset		= CMU_CMU_TOP_CONTROLLER_OPTION,
+	.drcg_offset		= EXYNOS5515_DRCG_EN_OFFSET,
+};
+
+static void __init exynos5515_cmu_top_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
+}
+
+/* Register CMU_TOP early, as it's a dependency for other early domains */
+CLK_OF_DECLARE(exynos5515_cmu_top, "samsung,exynos5515-cmu-top",
+	       exynos5515_cmu_top_init);
+
+/* ---- CMU_PERI ------------------------------------------------------------ */
+
+/*
+ * CMU_PERI:	0x10030000
+ * SYSREG_PERI:	0x10020000
+ */
+
+#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER					0x0600
+#define PLL_CON1_MUX_CLKCMU_PERI_BUS_USER					0x0604
+#define PLL_CON0_MUX_CLKCMU_PERI_IP_USER					0x0610
+#define PLL_CON1_MUX_CLKCMU_PERI_IP_USER					0x0614
+#define PLL_CON0_MUX_CLKCMU_PERI_UART_USER					0x0620
+#define PLL_CON1_MUX_CLKCMU_PERI_UART_USER					0x0624
+#define PERI_CMU_PERI_CONTROLLER_OPTION						0x0800
+#define CLK_CON_MUX_MUX_CLK_PERI_SPI						0x1000
+#define CLK_CON_MUX_MUX_CLK_PERI_USI00_USI					0x1004
+#define CLK_CON_DIV_CLKCMU_OTP							0x1800
+#define CLK_CON_DIV_DIV_CLK_PERI_I2C_0						0x1804
+#define CLK_CON_DIV_DIV_CLK_PERI_I2C_1						0x1808
+#define CLK_CON_DIV_DIV_CLK_PERI_I2C_2						0x180c
+#define CLK_CON_DIV_DIV_CLK_PERI_I2C_3						0x1810
+#define CLK_CON_DIV_DIV_CLK_PERI_SPI						0x1814
+#define CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C					0x1818
+#define CLK_CON_DIV_DIV_CLK_PERI_USI00_USI					0x181c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK			0x2000
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK			0x2004
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK			0x2008
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK			0x200c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK			0x2010
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK			0x2014
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK			0x2018
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK			0x201c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK			0x2020
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK			0x2024
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK			0x2028
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK				0x202c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK		0x2030
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK			0x2034
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK		0x2038
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0		0x203c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK	0x2040
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK	0x2044
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK	0x2048
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK	0x204c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK	0x2050
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK	0x2054
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK	0x2058
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK	0x205c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK	0x2060
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK	0x2064
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK		0x2068
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK			0x206c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK			0x2070
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK			0x2074
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK			0x2078
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK			0x207c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK			0x2080
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK			0x2084
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK			0x2088
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK			0x208c
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK			0x2090
+#define CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK			0x2094
+#define CLK_CON_GAT_GATE_CLK_PERI_I2C_0						0x2098
+#define CLK_CON_GAT_GATE_CLK_PERI_I2C_1						0x209c
+#define CLK_CON_GAT_GATE_CLK_PERI_I2C_2						0x20a0
+#define CLK_CON_GAT_GATE_CLK_PERI_I2C_3						0x20a4
+#define CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C					0x20a8
+
+static const unsigned long peri_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
+	PLL_CON1_MUX_CLKCMU_PERI_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_PERI_IP_USER,
+	PLL_CON1_MUX_CLKCMU_PERI_IP_USER,
+	PLL_CON0_MUX_CLKCMU_PERI_UART_USER,
+	PLL_CON1_MUX_CLKCMU_PERI_UART_USER,
+	PERI_CMU_PERI_CONTROLLER_OPTION,
+	CLK_CON_MUX_MUX_CLK_PERI_SPI,
+	CLK_CON_MUX_MUX_CLK_PERI_USI00_USI,
+	CLK_CON_DIV_CLKCMU_OTP,
+	CLK_CON_DIV_DIV_CLK_PERI_I2C_0,
+	CLK_CON_DIV_DIV_CLK_PERI_I2C_1,
+	CLK_CON_DIV_DIV_CLK_PERI_I2C_2,
+	CLK_CON_DIV_DIV_CLK_PERI_I2C_3,
+	CLK_CON_DIV_DIV_CLK_PERI_SPI,
+	CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C,
+	CLK_CON_DIV_DIV_CLK_PERI_USI00_USI,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GATE_CLK_PERI_I2C_0,
+	CLK_CON_GAT_GATE_CLK_PERI_I2C_1,
+	CLK_CON_GAT_GATE_CLK_PERI_I2C_2,
+	CLK_CON_GAT_GATE_CLK_PERI_I2C_3,
+	CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C,
+};
+
+/* Parent clock list for CMU_PERI muxes */
+PNAME(mout_pll_peri_bus_user_p)		= { "oscclk",
+					    "mout_cmu_peri_bus" };
+
+PNAME(mout_pll_peri_ip_user_p)		= { "oscclk",
+					    "mout_cmu_peri_ip" };
+
+/* Parent clock list for CMU_PERI muxes: for SPI */
+PNAME(mout_peri_spi_p)			= { "oscclk",
+					    "mout_pll_peri_ip_user" };
+
+/* Parent clock list for CMU_PERI muxes: for UART */
+PNAME(mout_pll_peri_uart_user_p)	= { "oscclk",
+					    "mout_cmu_peri_uart" };
+
+/* Parent clock list for CMU_PERI muxes: for USI */
+PNAME(mout_peri_usi00_usi_p)		= { "oscclk",
+					    "mout_pll_peri_ip_user" };
+
+static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
+	/* BUS */
+	MUX(CLK_MOUT_PLL_PERI_BUS_USER, "mout_pll_peri_bus_user",
+	    mout_pll_peri_bus_user_p,
+	    PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
+	    4, 1),
+
+	/* IP */
+	MUX(CLK_MOUT_PLL_PERI_IP_USER, "mout_pll_peri_ip_user",
+	    mout_pll_peri_ip_user_p,
+	    PLL_CON0_MUX_CLKCMU_PERI_IP_USER,
+	    4, 1),
+
+	/* SPI */
+	MUX(CLK_MOUT_PERI_SPI, "mout_peri_spi",
+	    mout_peri_spi_p,
+	    CLK_CON_MUX_MUX_CLK_PERI_SPI,
+	    0, 1),
+
+	/* UART */
+	MUX(CLK_MOUT_PLL_PERI_UART_USER, "mout_pll_peri_uart_user",
+	    mout_pll_peri_uart_user_p,
+	    PLL_CON0_MUX_CLKCMU_PERI_UART_USER,
+	    4, 1),
+
+	/* USI (Universal Serial Interface) */
+	MUX(CLK_MOUT_PERI_USI00_USI, "mout_peri_usi00_usi",
+	    mout_peri_usi00_usi_p,
+	    CLK_CON_MUX_MUX_CLK_PERI_USI00_USI,
+	    0, 1),
+};
+
+static const struct samsung_div_clock peri_div_clks[] __initconst = {
+	/* I2C */
+	DIV(CLK_DOUT_PERI_I2C_0, "dout_peri_i2c_0",
+	    "gout_peri_i2c_0",
+	    CLK_CON_DIV_DIV_CLK_PERI_I2C_0,
+	    0, 4),
+	DIV(CLK_DOUT_PERI_I2C_1, "dout_peri_i2c_1",
+	    "gout_peri_i2c_1",
+	    CLK_CON_DIV_DIV_CLK_PERI_I2C_1,
+	    0, 4),
+	DIV(CLK_DOUT_PERI_I2C_2, "dout_peri_i2c_2",
+	    "gout_peri_i2c_2",
+	    CLK_CON_DIV_DIV_CLK_PERI_I2C_2,
+	    0, 4),
+	DIV(CLK_DOUT_PERI_I2C_3, "dout_peri_i2c_3",
+	    "gout_peri_i2c_3",
+	    CLK_CON_DIV_DIV_CLK_PERI_I2C_3,
+	    0, 4),
+
+	/* SPI */
+	DIV(CLK_DOUT_PERI_SPI, "dout_peri_spi",
+	    "mout_peri_spi",
+	    CLK_CON_DIV_DIV_CLK_PERI_SPI,
+	    0, 5),
+
+	/* USI */
+	DIV(CLK_DOUT_PERI_USI00_I2C, "dout_peri_usi00_i2c",
+	    "gout_peri_usi00_i2c",
+	    CLK_CON_DIV_DIV_CLK_PERI_USI00_I2C,
+	    0, 4),
+	DIV(CLK_DOUT_PERI_USI00_USI, "dout_peri_usi00_usi",
+	    "mout_peri_usi00_usi",
+	    CLK_CON_DIV_DIV_CLK_PERI_USI00_USI,
+	    0, 5),
+};
+
+static const struct samsung_fixed_factor_clock peri_fixed_factor_clks[] __initconst = {
+	/* OTP (One-Time Programmable eFuses) */
+	FFACTOR(CLK_DOUT_PERI_OTP, "dout_peri_otp", "oscclk",
+		1, 8, 0),
+};
+
+static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
+	/* BUS */
+	GATE(CLK_GOUT_PERI_BUSIF_TMU_PCLK, "gout_peri_busif_tmu_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_BUSIF_TMU_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_BUS_CLK, "gout_peri_bus_clk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_BUS_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* CMU */
+	GATE(CLK_GOUT_PERI_CMU_PCLK, "gout_peri_cmu_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_PERI_CMU_PERI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* GPIO */
+	GATE(CLK_GOUT_PERI_GPIO_PCLK, "gout_peri_gpio_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_GPIO_PERI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* I2C */
+	GATE(CLK_GOUT_PERI_I2C_0_IPCLK, "gout_peri_i2c_0_ipclk",
+	     "dout_peri_i2c_0",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_0_PCLK, "gout_peri_i2c_0_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_1_IPCLK, "gout_peri_i2c_1_ipclk",
+	     "dout_peri_i2c_1",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_1_PCLK, "gout_peri_i2c_1_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_2_IPCLK, "gout_peri_i2c_2_ipclk",
+	     "dout_peri_i2c_2",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_2_PCLK, "gout_peri_i2c_2_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_2_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_3_IPCLK, "gout_peri_i2c_3_ipclk",
+	     "dout_peri_i2c_3",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_3_PCLK, "gout_peri_i2c_3_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_I2C_3_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_0_CLK, "gout_peri_i2c_0_clk",
+	     "dout_peri_i2c_0",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_0_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_1_CLK, "gout_peri_i2c_1_clk",
+	     "dout_peri_i2c_1",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_1_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_2_CLK, "gout_peri_i2c_2_clk",
+	     "dout_peri_i2c_2",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_2_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_3_CLK, "gout_peri_i2c_3_clk",
+	     "dout_peri_i2c_3",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_I2C_3_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_0, "gout_peri_i2c_0",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_I2C_0,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_1, "gout_peri_i2c_1",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_I2C_1,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_2, "gout_peri_i2c_2",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_I2C_2,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_I2C_3, "gout_peri_i2c_3",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_I2C_3,
+	     21, 0, 0),
+
+	/* MCT (Multi-Core Timer) */
+	GATE(CLK_GOUT_PERI_MCT_PCLK, "gout_peri_mct_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_MCT_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* OTP */
+	GATE(CLK_GOUT_PERI_OTP_OSCCLK, "gout_peri_otp_oscclk",
+	     "oscclk",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_OTP_PCLK, "gout_peri_otp_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_OTP_CON_TOP_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* OSCCLK */
+	GATE(CLK_GOUT_PERI_OSCCLK, "gout_peri_oscclk",
+	     "oscclk",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_OSCCLK_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* PWM */
+	GATE(CLK_GOUT_PERI_PWM_MOTOR_PCLK, "gout_peri_pwm_motor_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_PWM_MOTOR_IPCLKPORT_I_PCLK_S0,
+	     21, 0, 0),
+
+	/* SPI */
+	GATE(CLK_GOUT_PERI_SPI_CLK, "gout_peri_spi_clk",
+	     "dout_peri_spi",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_SPI_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* SYSREG */
+	GATE(CLK_GOUT_PERI_SYSREG_PCLK, "gout_peri_sysreg_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_SYSREG_PERI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* TZ */
+	GATE(CLK_GOUT_PERI_D_TZPC_PCLK, "gout_peri_d_tzpc_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_D_TZPC_PERI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* UART */
+	GATE(CLK_GOUT_PERI_UART_CLK, "gout_peri_uart_clk",
+	     "mout_pll_peri_uart_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_UART_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* USI */
+	GATE(CLK_GOUT_PERI_USI00_I2C_CLK, "gout_peri_usi00_i2c_clk",
+	     "dout_peri_usi00_i2c",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_I2C_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_USI_CLK, "gout_peri_usi00_usi_clk",
+	     "dout_peri_usi00_usi",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_RSTNSYNC_CLK_PERI_USI00_USI_IPCLKPORT_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_I2C_IPCLK, "gout_peri_usi00_i2c_ipclk",
+	     "dout_peri_usi00_i2c",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_I2C_PCLK, "gout_peri_usi00_i2c_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_I2C_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_USI_IPCLK, "gout_peri_usi00_usi_ipclk",
+	     "dout_peri_usi00_usi",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_USI_PCLK, "gout_peri_usi00_usi_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI00_USI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI_SPI_IPCLK, "gout_peri_usi_spi_ipclk",
+	     "dout_peri_spi",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI_SPI_PCLK, "gout_peri_usi_spi_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI_SPI_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI_UART_IPCLK, "gout_peri_usi_uart_ipclk",
+	     "mout_pll_peri_uart_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_IPCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI_UART_PCLK, "gout_peri_usi_uart_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_USI_UART_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_USI00_I2C, "gout_peri_usi00_i2c",
+	     "mout_pll_peri_ip_user",
+	     CLK_CON_GAT_GATE_CLK_PERI_USI00_I2C,
+	     21, 0, 0),
+
+	/* WDT (Watchdog Timer) */
+	GATE(CLK_GOUT_PERI_WDT0_PCLK, "gout_peri_wdt0_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_WDT0_IPCLKPORT_PCLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_PERI_WDT1_PCLK, "gout_peri_wdt1_pclk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_WDT1_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* UNKNOWN */
+	GATE(CLK_GOUT_PERI_SLH_AXI_MI_P_CLK, "gout_peri_slh_axi_mi_p_clk",
+	     "mout_pll_peri_bus_user",
+	     CLK_CON_GAT_CLK_BLK_PERI_UID_SLH_AXI_MI_P_PERI_IPCLKPORT_I_CLK,
+	     21, 0, 0),
+};
+
+static const struct samsung_cmu_info peri_cmu_info __initconst = {
+	.mux_clks		= peri_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(peri_mux_clks),
+	.div_clks		= peri_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(peri_div_clks),
+	.fixed_factor_clks	= peri_fixed_factor_clks,
+	.nr_fixed_factor_clks	= ARRAY_SIZE(peri_fixed_factor_clks),
+	.gate_clks		= peri_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(peri_gate_clks),
+	.nr_clk_ids		= CLKS_NR_PERI,
+	.clk_regs		= peri_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(peri_clk_regs),
+	.sysreg_clk_regs	= drcg_sysreg,
+	.nr_sysreg_clk_regs	= ARRAY_SIZE(drcg_sysreg),
+	.clk_name		= "bus",
+	.auto_clock_gate	= true,
+	.gate_dbg_offset	= EXYNOS5515_GATE_DBG_OFFSET,
+	.option_offset		= PERI_CMU_PERI_CONTROLLER_OPTION,
+	.drcg_offset		= EXYNOS5515_DRCG_EN_OFFSET,
+};
+
+static void __init exynos5515_cmu_peri_init(struct device_node *np)
+{
+	exynos_arm64_register_cmu(NULL, np, &peri_cmu_info);
+}
+
+/* Register CMU_PERI early, as it's a dependency for the MCT. */
+CLK_OF_DECLARE(exynos5515_cmu_peri, "samsung,exynos5515-cmu-peri",
+	       exynos5515_cmu_peri_init);
+
+/* ---- CMU_FSYS ------------------------------------------------------------ */
+
+/*
+ * CMU_FSYS:	0x10400000
+ * SYSREG_FSYS:	0x10420000
+ */
+
+#define PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER						0x0600
+#define PLL_CON1_MUX_CLKCMU_FSYS_BUS_USER						0x0604
+#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER						0x0610
+#define PLL_CON1_MUX_CLKCMU_FSYS_MMC_CARD_USER						0x0614
+#define PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER						0x0620
+#define PLL_CON1_MUX_CLKCMU_FSYS_MMC_EMBD_USER						0x0624
+#define PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER						0x0630
+#define PLL_CON1_MUX_CLKCMU_FSYS_USB20DRD_USER						0x0634
+#define FSYS_CMU_FSYS_CONTROLLER_OPTION							0x0800
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK			0x2000
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN				0x2004
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN				0x2008
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK		0x200c
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50	0x2010
+#define CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26	0x2014
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK			0x2018
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK				0x201c
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK				0x2020
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK				0x2024
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK				0x2028
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK				0x202c
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK		0x2030
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK			0x2034
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK			0x2038
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK			0x203c
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20		0x2040
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY		0x2044
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK			0x2048
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK				0x204c
+#define CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK				0x2050
+
+static const unsigned long fsys_clk_regs[] __initconst = {
+	PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER,
+	PLL_CON1_MUX_CLKCMU_FSYS_BUS_USER,
+	PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER,
+	PLL_CON1_MUX_CLKCMU_FSYS_MMC_CARD_USER,
+	PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER,
+	PLL_CON1_MUX_CLKCMU_FSYS_MMC_EMBD_USER,
+	PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER,
+	PLL_CON1_MUX_CLKCMU_FSYS_USB20DRD_USER,
+	FSYS_CMU_FSYS_CONTROLLER_OPTION,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50,
+	CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK,
+	CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK,
+};
+
+/* Parent clock list for CMU_FSYS muxes */
+PNAME(mout_pll_fsys_bus_user_p)		= { "dout_cmu_fsys_bus",
+					    "oscclk" };
+
+/* Parent clock list for CMU_FSYS muxes: for MMC */
+PNAME(mout_pll_fsys_mmc_card_user_p)	= { "dout_cmu_fsys_mmc_card",
+					    "oscclk" };
+
+PNAME(mout_pll_fsys_mmc_embd_user_p)	= { "dout_cmu_fsys_mmc_embd",
+					    "oscclk" };
+
+/* Parent clock list for CMU_FSYS muxes: for USB */
+PNAME(mout_pll_fsys_usb20drd_user_p)	= { "dout_cmu_fsys_usb20drd",
+					    "oscclk" };
+
+static const struct samsung_mux_clock fsys_mux_clks[] __initconst = {
+	/* BUS */
+	MUX(CLK_MOUT_PLL_FSYS_BUS_USER, "mout_pll_fsys_bus_user",
+	    mout_pll_fsys_bus_user_p,
+	    PLL_CON0_MUX_CLKCMU_FSYS_BUS_USER,
+	    4, 1),
+
+	/* MMC */
+	MUX(CLK_MOUT_PLL_FSYS_MMC_CARD_USER, "mout_pll_fsys_mmc_card_user",
+	    mout_pll_fsys_mmc_card_user_p,
+	    PLL_CON0_MUX_CLKCMU_FSYS_MMC_CARD_USER,
+	    4, 1),
+	MUX(CLK_MOUT_PLL_FSYS_MMC_EMBD_USER, "mout_pll_fsys_mmc_embd_user",
+	    mout_pll_fsys_mmc_embd_user_p,
+	    PLL_CON0_MUX_CLKCMU_FSYS_MMC_EMBD_USER,
+	    4, 1),
+
+	/* USB */
+	MUX(CLK_MOUT_PLL_FSYS_USB20DRD_USER, "mout_pll_fsys_usb20drd_user",
+	    mout_pll_fsys_usb20drd_user_p,
+	    PLL_CON0_MUX_CLKCMU_FSYS_USB20DRD_USER,
+	    4, 1),
+};
+
+static const struct samsung_gate_clock fsys_gate_clks[] __initconst = {
+	/* BUS */
+	GATE(CLK_GOUT_FSYS_BUS_CLK, "gout_fsys_bus_clk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_BUS_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* CMU */
+	GATE(CLK_GOUT_FSYS_CMU_PCLK, "gout_fsys_cmu_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_FSYS_CMU_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* GPIO */
+	GATE(CLK_GOUT_FSYS_GPIO_PCLK, "gout_fsys_gpio_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_GPIO_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* MMC */
+	GATE(CLK_GOUT_FSYS_MMC_CARD_SDCLKIN, "gout_fsys_mmc_card_sdclkin",
+	     "mout_pll_fsys_mmc_card_user",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_SDCLKIN,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_MMC_EMBD_SDCLKIN, "gout_fsys_mmc_embd_sdclkin",
+	     "mout_pll_fsys_mmc_embd_user",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_SDCLKIN,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_MMC_CARD_ACLK, "gout_fsys_mmc_card_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_CARD_IPCLKPORT_I_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_MMC_EMBD_ACLK, "gout_fsys_mmc_embd_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_MMC_EMBD_IPCLKPORT_I_ACLK,
+	     21, 0, 0),
+
+	/* OSCCLK */
+	GATE(CLK_GOUT_FSYS_OSCCLK, "gout_fsys_oscclk",
+	     "oscclk",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_RSTNSYNC_CLK_FSYS_OSCCLK_IPCLKPORT_CLK,
+	     21, 0, 0),
+
+	/* PMU */
+	GATE(CLK_GOUT_FSYS_PPMU_ACLK, "gout_fsys_ppmu_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_PPMU_PCLK, "gout_fsys_ppmu_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_PPMU_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* SYSREG */
+	GATE(CLK_GOUT_FSYS_SYSREG_PCLK, "gout_fsys_sysreg_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_SYSREG_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* TZ */
+	GATE(CLK_GOUT_FSYS_D_TZPC_PCLK, "gout_fsys_d_tzpc_pclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_D_TZPC_FSYS_IPCLKPORT_PCLK,
+	     21, 0, 0),
+
+	/* USB */
+	GATE(CLK_GOUT_FSYS_USB20DRD_REFCLK,
+	     "gout_fsys_usb20drd_refclk",
+	     "mout_pll_fsys_usb20drd_user",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20DRD_REF_CLK_50,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_USB20DRD_PHY_REFCLK,
+	     "gout_fsys_usb20drd_phy_refclk",
+	     "oscclk",
+	     CLK_CON_GAT_CLK_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_I_USB20_PHY_REFCLK_26,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_USB20DRD_ACLK_PHYCTRL,
+	     "gout_fsys_usb20drd_aclk_phyctrl",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_ACLK_PHYCTRL_20,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_USB20DRD_BUS_CLK_EARLY,
+	     "gout_fsys_usb20drd_bus_clk_early",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_USB20DRD_TOP_IPCLKPORT_BUS_CLK_EARLY,
+	     21, 0, 0),
+
+	/* UNKNOWN */
+	GATE(CLK_GOUT_FSYS_SLH_AXI_MI_P_CLK, "gout_fsys_slh_axi_mi_p_clk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_MI_P_FSYS_IPCLKPORT_I_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_SLH_AXI_SI_D_CLK, "gout_fsys_slh_axi_si_d_clk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_SLH_AXI_SI_D_FSYS_IPCLKPORT_I_CLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_US_64TO128_ACLK, "gout_fsys_us_64to128_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_US_64TO128_FSYS_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_XIU_D_ACLK, "gout_fsys_xiu_d_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_D_FSYS_IPCLKPORT_ACLK,
+	     21, 0, 0),
+	GATE(CLK_GOUT_FSYS_XIU_P_ACLK, "gout_fsys_xiu_p_aclk",
+	     "mout_pll_fsys_bus_user",
+	     CLK_CON_GAT_GOUT_BLK_FSYS_UID_XIU_P_FSYS_IPCLKPORT_ACLK,
+	     21, 0, 0),
+};
+
+static const struct samsung_cmu_info fsys_cmu_info __initconst = {
+	.mux_clks		= fsys_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys_mux_clks),
+	.gate_clks		= fsys_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys_gate_clks),
+	.nr_clk_ids		= CLKS_NR_FSYS,
+	.clk_regs		= fsys_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys_clk_regs),
+	.sysreg_clk_regs	= drcg_sysreg,
+	.nr_sysreg_clk_regs	= ARRAY_SIZE(drcg_sysreg),
+	.clk_name		= "bus",
+	.auto_clock_gate	= true,
+	.gate_dbg_offset	= EXYNOS5515_GATE_DBG_OFFSET,
+	.option_offset		= FSYS_CMU_FSYS_CONTROLLER_OPTION,
+	.drcg_offset		= EXYNOS5515_DRCG_EN_OFFSET,
+};
+
+/* ----- platform_driver ----- */
+
+static int __init exynos5515_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+static const struct of_device_id exynos5515_cmu_of_match[] = {
+	{
+		.compatible = "samsung,exynos5515-cmu-fsys",
+		.data = &fsys_cmu_info,
+	},
+	{ },
+};
+
+static struct platform_driver exynos5515_cmu_driver __refdata = {
+	.driver = {
+		.name = "exynos5515-cmu",
+		.of_match_table = exynos5515_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = exynos5515_cmu_probe,
+};
+
+static int __init exynos5515_cmu_init(void)
+{
+	return platform_driver_register(&exynos5515_cmu_driver);
+}
+
+core_initcall(exynos5515_cmu_init);

-- 
2.54.0


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

* Re: [PATCH 3/3] clk: samsung: Introduce Exynos5515 clock driver
  2026-08-17 10:17   ` Aiden Isik
  (?)
@ 2026-08-17 10:27   ` sashiko-bot
  2026-08-17 11:12     ` Aiden Isik
  -1 siblings, 1 reply; 12+ messages in thread
From: sashiko-bot @ 2026-08-17 10:27 UTC (permalink / raw)
  To: Aiden Isik; +Cc: robh, linux-clk, devicetree, conor+dt

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Clock Tree Misconfiguration / Unintended Clock Bypass in CMU_PERI
- [High] Incorrect Mux Parent Clock Order in CMU_FSYS User MUXes
- [Medium] Missing Initialization and State Preservation for EXYNOS5515_MEMCLK_OFFSET
--

--- Patch [3]: [PATCH 3/3] clk: samsung: Introduce Exynos5515 clock driver ---
commit 30844f6e4b1e1ae616f216fdbd770df29393e674
Author: Aiden Isik <aidenisik@member.fsf.org>

clk: samsung: Introduce Exynos5515 clock driver

CMU_TOP is the top level clock management unit which contains PLLs,
muxes, dividers and gates that feed the other clock management units.
CMU_PERI provides clocks for USI blocks and their children, PWM, MCT,
and watchdog timers. CMU_FSYS provides clocks for MMC, USB, GPIO, etc.

> diff --git a/drivers/clk/samsung/clk-exynos5515.c b/drivers/clk/samsung/clk-exynos5515.c
> new file mode 100644
> index 0000000000000..f989a13f1a574
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-exynos5515.c
> @@ -0,0 +1,1485 @@
> +// SPDX-License-Identifier: GPL-2.0-only

[ ... ]

> +static const unsigned long drcg_sysreg[] __initconst = {
> +	EXYNOS5515_DRCG_EN_OFFSET,
> +};

[Severity: Medium]
Is it intended that EXYNOS5515_MEMCLK_OFFSET is missing from the drcg_sysreg
array? Without this offset, the memory clock gating state won't be saved or
restored across power management suspend/resume cycles.

> +
> +static const struct samsung_cmu_info top_cmu_info __initconst = {

[ ... ]

> +	.gate_dbg_offset	= EXYNOS5515_GATE_DBG_OFFSET,
> +	.option_offset		= CMU_CMU_TOP_CONTROLLER_OPTION,
> +	.drcg_offset		= EXYNOS5515_DRCG_EN_OFFSET,
> +};

[Severity: Medium]
Will this break the dynamic root clock gating initialization? The
.memclk_offset = EXYNOS5515_MEMCLK_OFFSET assignment seems to be missing
here, which might prevent samsung_en_dyn_root_clk_gating() from enabling the
memory clock gate correctly.

[ ... ]

> +/* Parent clock list for CMU_PERI muxes */
> +PNAME(mout_pll_peri_bus_user_p)		= { "oscclk",
> +					    "mout_cmu_peri_bus" };
> +
> +PNAME(mout_pll_peri_ip_user_p)		= { "oscclk",
> +					    "mout_cmu_peri_ip" };

[Severity: High]
Does this correctly route the clocks from CMU_TOP? Referencing the
intermediate mout_cmu_peri_* clocks here instead of the final
dout_cmu_peri_* dividers appears to bypass the hardware gates and dividers
defined in CMU_TOP. Could this lead to incorrect clock rate calculations and
resource leaks if the CMU_TOP blocks fail to gate when PERI clocks are
disabled?

[ ... ]

> +/* Parent clock list for CMU_FSYS muxes */
> +PNAME(mout_pll_fsys_bus_user_p)		= { "dout_cmu_fsys_bus",
> +					    "oscclk" };
> +
> +/* Parent clock list for CMU_FSYS muxes: for MMC */
> +PNAME(mout_pll_fsys_mmc_card_user_p)	= { "dout_cmu_fsys_mmc_card",
> +					    "oscclk" };
> +
> +PNAME(mout_pll_fsys_mmc_embd_user_p)	= { "dout_cmu_fsys_mmc_embd",
> +					    "oscclk" };
> +
> +/* Parent clock list for CMU_FSYS muxes: for USB */
> +PNAME(mout_pll_fsys_usb20drd_user_p)	= { "dout_cmu_fsys_usb20drd",
> +					    "oscclk" };

[Severity: High]
Is the parent clock order inverted in these MUXes? User MUX arrays like those
in CMU_PERI map oscclk to hardware value 0 and the bus clock to 1. Since the
clock framework uses the array index for the register value, placing oscclk
at index 1 here will write 0 when requesting the high-speed bus clock,
inadvertently selecting the 26MHz oscclk instead. Could this cause
performance degradation and hardware instability?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260817-for-next-lucky7-clock-v1-0-032e4b229c76@member.fsf.org?part=3

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

* Re: [PATCH 2/3] clk: samsung: clk-pll: Add support for pll_309
  2026-08-17 10:17   ` Aiden Isik
  (?)
@ 2026-08-17 10:37   ` sashiko-bot
  2026-08-17 11:47     ` Aiden Isik
  -1 siblings, 1 reply; 12+ messages in thread
From: sashiko-bot @ 2026-08-17 10:37 UTC (permalink / raw)
  To: Aiden Isik; +Cc: linux-clk, conor+dt, robh, devicetree

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Logic Error / Out-of-bounds Read when rate_table is empty
- [Medium] Single-Responsibility Violation: Undocumented architectural refactoring
--

--- Patch [2]: [PATCH 2/3] clk: samsung: clk-pll: Add support for pll_309 ---
commit d62df56ff2e6bf73437e6e25e1335b3fb4571268
Author: Aiden Isik <aidenisik@member.fsf.org>

clk: samsung: clk-pll: Add support for pll_309

This commit adds support for the pll_309 used in the Exynos5515 SoC, defining
the PLL characteristics which are handled similarly to pll_531x.

> diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
> index e74552846ba34..8b1474aeaf0c8 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -1593,32 +1593,35 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
>  {
>  	struct samsung_clk_pll *pll;
>  	struct clk_init_data init;
> -	unsigned int len = 0;
> -	int ret;
> +	int ret, len;
>  
> -	if (pll_clk->rate_table) {
> -		/* find count of rates in rate_table */
> -		while (pll_clk->rate_table[len].rate != 0)
> -			len++;
> -	}
> -
> -	pll = kzalloc_flex(*pll, rate_table, len);
> +	pll = kzalloc_obj(*pll);

[Severity: Medium]
This isn't a bug, but the commit message only mentions adding support for the
new pll_309 type, while this code changes the allocation semantics of the
rate_table across the entire driver, switching from a flexible array member
to a separate pointer allocation. 

Could this architectural refactoring be split into a separate patch or
documented in the commit message?

[ ... ]

> @@ -1637,7 +1640,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
>  	case pll_a9fracm:
>  		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
>  		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
> -		if (!pll->rate_count)
> +		if (!pll->rate_table)

[Severity: High]
If a clock is registered with an empty rate table containing only the zero
terminator, kmemdup_array() is called with a count of 0 earlier in this
function and returns ZERO_SIZE_PTR rather than NULL.

Since ZERO_SIZE_PTR is not NULL, this check evaluates to false, which
incorrectly assigns the full operations instead of the safe min_ops fallback.

If samsung_pll_determine_rate() is subsequently called, it skips its loop
because rate_count is 0, and attempts to access rate_table[-1]:

samsung_pll_determine_rate() {
    ...
    req->rate = rate_table[i - 1].rate;
}

Since rate_table is ZERO_SIZE_PTR, will this result in an out-of-bounds
memory read?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260817-for-next-lucky7-clock-v1-0-032e4b229c76@member.fsf.org?part=2

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

* Re: [PATCH 3/3] clk: samsung: Introduce Exynos5515 clock driver
  2026-08-17 10:27   ` sashiko-bot
@ 2026-08-17 11:12     ` Aiden Isik
  0 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik @ 2026-08-17 11:12 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: Aiden Isik, robh, linux-clk, devicetree, conor+dt


> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> - [High] Clock Tree Misconfiguration / Unintended Clock Bypass in CMU_PERI
> - [High] Incorrect Mux Parent Clock Order in CMU_FSYS User MUXes
> - [Medium] Missing Initialization and State Preservation for EXYNOS5515_MEMCLK_OFFSET
> --
> 
> --- Patch [3]: [PATCH 3/3] clk: samsung: Introduce Exynos5515 clock driver ---
> commit 30844f6e4b1e1ae616f216fdbd770df29393e674
> Author: Aiden Isik <aidenisik@member.fsf.org>
> 
> clk: samsung: Introduce Exynos5515 clock driver
> 
> CMU_TOP is the top level clock management unit which contains PLLs,
> muxes, dividers and gates that feed the other clock management units.
> CMU_PERI provides clocks for USI blocks and their children, PWM, MCT,
> and watchdog timers. CMU_FSYS provides clocks for MMC, USB, GPIO, etc.
> 
> > diff --git a/drivers/clk/samsung/clk-exynos5515.c b/drivers/clk/samsung/clk-exynos5515.c
> > new file mode 100644
> > index 0000000000000..f989a13f1a574
> > --- /dev/null
> > +++ b/drivers/clk/samsung/clk-exynos5515.c
> > @@ -0,0 +1,1485 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> 
> [ ... ]
> 
> > +static const unsigned long drcg_sysreg[] __initconst = {
> > +	EXYNOS5515_DRCG_EN_OFFSET,
> > +};
> 
> [Severity: Medium]
> Is it intended that EXYNOS5515_MEMCLK_OFFSET is missing from the drcg_sysreg
> array? Without this offset, the memory clock gating state won't be saved or
> restored across power management suspend/resume cycles.
> 
> > +
> > +static const struct samsung_cmu_info top_cmu_info __initconst = {
> 
> [ ... ]
> 
> > +	.gate_dbg_offset	= EXYNOS5515_GATE_DBG_OFFSET,
> > +	.option_offset		= CMU_CMU_TOP_CONTROLLER_OPTION,
> > +	.drcg_offset		= EXYNOS5515_DRCG_EN_OFFSET,
> > +};
> 

This is intentional, downstream only has this on a few blocks and
these are not amongst those blocks. Will see if a maintainer agrees.

> [Severity: Medium]
> Will this break the dynamic root clock gating initialization? The
> .memclk_offset = EXYNOS5515_MEMCLK_OFFSET assignment seems to be missing
> here, which might prevent samsung_en_dyn_root_clk_gating() from enabling the
> memory clock gate correctly.
> 

See above.

> [ ... ]
> 
> > +/* Parent clock list for CMU_PERI muxes */
> > +PNAME(mout_pll_peri_bus_user_p)		= { "oscclk",
> > +					    "mout_cmu_peri_bus" };
> > +
> > +PNAME(mout_pll_peri_ip_user_p)		= { "oscclk",
> > +					    "mout_cmu_peri_ip" };
> 
> [Severity: High]
> Does this correctly route the clocks from CMU_TOP? Referencing the
> intermediate mout_cmu_peri_* clocks here instead of the final
> dout_cmu_peri_* dividers appears to bypass the hardware gates and dividers
> defined in CMU_TOP. Could this lead to incorrect clock rate calculations and
> resource leaks if the CMU_TOP blocks fail to gate when PERI clocks are
> disabled?

Unsure, but this is how downstream does it.

> 
> [ ... ]
> 
> > +/* Parent clock list for CMU_FSYS muxes */
> > +PNAME(mout_pll_fsys_bus_user_p)		= { "dout_cmu_fsys_bus",
> > +					    "oscclk" };
> > +
> > +/* Parent clock list for CMU_FSYS muxes: for MMC */
> > +PNAME(mout_pll_fsys_mmc_card_user_p)	= { "dout_cmu_fsys_mmc_card",
> > +					    "oscclk" };
> > +
> > +PNAME(mout_pll_fsys_mmc_embd_user_p)	= { "dout_cmu_fsys_mmc_embd",
> > +					    "oscclk" };
> > +
> > +/* Parent clock list for CMU_FSYS muxes: for USB */
> > +PNAME(mout_pll_fsys_usb20drd_user_p)	= { "dout_cmu_fsys_usb20drd",
> > +					    "oscclk" };
> 
> [Severity: High]
> Is the parent clock order inverted in these MUXes? User MUX arrays like those
> in CMU_PERI map oscclk to hardware value 0 and the bus clock to 1. Since the
> clock framework uses the array index for the register value, placing oscclk
> at index 1 here will write 0 when requesting the high-speed bus clock,
> inadvertently selecting the 26MHz oscclk instead. Could this cause
> performance degradation and hardware instability?
> 

Possibly, I thought the ordering was just cosmetic and for the
kernel's informational purposes. HWACG seems to mask the problem
if there is one but will still fix in v2.

> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260817-for-next-lucky7-clock-v1-0-032e4b229c76@member.fsf.org?part=3
> 

Kind regards,
- Aiden Isik

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

* Re: [PATCH 2/3] clk: samsung: clk-pll: Add support for pll_309
  2026-08-17 10:37   ` sashiko-bot
@ 2026-08-17 11:47     ` Aiden Isik
  0 siblings, 0 replies; 12+ messages in thread
From: Aiden Isik @ 2026-08-17 11:47 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: Aiden Isik, linux-clk, conor+dt, robh, devicetree

> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] Logic Error / Out-of-bounds Read when rate_table is empty
> - [Medium] Single-Responsibility Violation: Undocumented architectural refactoring
> --
> 
> --- Patch [2]: [PATCH 2/3] clk: samsung: clk-pll: Add support for pll_309 ---
> commit d62df56ff2e6bf73437e6e25e1335b3fb4571268
> Author: Aiden Isik <aidenisik@member.fsf.org>
> 
> clk: samsung: clk-pll: Add support for pll_309
> 
> This commit adds support for the pll_309 used in the Exynos5515 SoC, defining
> the PLL characteristics which are handled similarly to pll_531x.
> 
> > diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
> > index e74552846ba34..8b1474aeaf0c8 100644
> > --- a/drivers/clk/samsung/clk-pll.c
> > +++ b/drivers/clk/samsung/clk-pll.c
> > @@ -1593,32 +1593,35 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
> >  {
> >  	struct samsung_clk_pll *pll;
> >  	struct clk_init_data init;
> > -	unsigned int len = 0;
> > -	int ret;
> > +	int ret, len;
> >
> > -	if (pll_clk->rate_table) {
> > -		/* find count of rates in rate_table */
> > -		while (pll_clk->rate_table[len].rate != 0)
> > -			len++;
> > -	}
> > -
> > -	pll = kzalloc_flex(*pll, rate_table, len);
> > +	pll = kzalloc_obj(*pll);
> 
> [Severity: Medium]
> This isn't a bug, but the commit message only mentions adding support for the
> new pll_309 type, while this code changes the allocation semantics of the
> rate_table across the entire driver, switching from a flexible array member
> to a separate pointer allocation.
> 
> Could this architectural refactoring be split into a separate patch or
> documented in the commit message?

This was a mistake caused when updating patches against next.
Will fix in v2.

> 
> [ ... ]
> 
> > @@ -1637,7 +1640,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
> >  	case pll_a9fracm:
> >  		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
> >  		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
> > -		if (!pll->rate_count)
> > +		if (!pll->rate_table)
> 
> [Severity: High]
> If a clock is registered with an empty rate table containing only the zero
> terminator, kmemdup_array() is called with a count of 0 earlier in this
> function and returns ZERO_SIZE_PTR rather than NULL.
> 
> Since ZERO_SIZE_PTR is not NULL, this check evaluates to false, which
> incorrectly assigns the full operations instead of the safe min_ops fallback.
> 
> If samsung_pll_determine_rate() is subsequently called, it skips its loop
> because rate_count is 0, and attempts to access rate_table[-1]:
> 
> samsung_pll_determine_rate() {
>     ...
>     req->rate = rate_table[i - 1].rate;
> }
> 
> Since rate_table is ZERO_SIZE_PTR, will this result in an out-of-bounds
> memory read?
> 
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260817-for-next-lucky7-clock-v1-0-032e4b229c76@member.fsf.org?part=2
> 

Kind regards,
- Aiden Isik

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

end of thread, other threads:[~2026-08-17 11:47 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-17 10:17 [PATCH 0/3] clk: samsung: Introduce Exynos5515 clock driver support Aiden Isik via B4 Relay
2026-08-17 10:17 ` Aiden Isik
2026-08-17 10:17 ` [PATCH 1/3] dt-bindings: clock: Add Exynos5515 SoC Aiden Isik via B4 Relay
2026-08-17 10:17   ` Aiden Isik
2026-08-17 10:17 ` [PATCH 2/3] clk: samsung: clk-pll: Add support for pll_309 Aiden Isik via B4 Relay
2026-08-17 10:17   ` Aiden Isik
2026-08-17 10:37   ` sashiko-bot
2026-08-17 11:47     ` Aiden Isik
2026-08-17 10:17 ` [PATCH 3/3] clk: samsung: Introduce Exynos5515 clock driver Aiden Isik via B4 Relay
2026-08-17 10:17   ` Aiden Isik
2026-08-17 10:27   ` sashiko-bot
2026-08-17 11:12     ` Aiden Isik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.