linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 0/3] [PATCH v6 0/3] Add support for AST2700 clk driver
@ 2024-10-28  5:30 Ryan Chen
  2024-10-28  5:30 ` [PATCH v7 1/3] dt-bindings: mfd: aspeed: support for AST2700 Ryan Chen
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Ryan Chen @ 2024-10-28  5:30 UTC (permalink / raw)
  To: ryan_chen, lee, robh, krzk+dt, conor+dt, joel, andrew, mturquette,
	sboyd, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, linux-clk, dmitry.baryshkov

This patch series is add clk driver for AST2700.

AST2700 is the 8th generation of Integrated Remote Management Processor
introduced by ASPEED Technology Inc. Which is Board Management controller
(BMC) SoC family. AST2700 have two SoC connected, one is SoC0, another
is SoC1, it has it's own scu, this driver inlcude SCU0 and SCU1 driver.

v7:
-reset-aspeed.h: fix declare static inline aspeed_reset_controller_register
if the function is not used.

v6:
-patch-2: add reset-aspeed.h
-reset-aspeed: add include cleanup.h for guard()
-reset-aspeed: change ids name clk_aspeed to reset_aspeed
-reset-aspeed: move aspeed_reset_controller_register,
aspeed_reset_adev_release, aspeed_reset_unregister_adev from clk-ast2700.c
-reset-aspeed: drop base check, since it check in clk-ast2700.c
-clk-ast2700: sync each gate name from *clk to *clk-gate name.
-clk-ast2700: add CLK_GATE_ASPEED to diff clk_hw_register_gate and
ast2700_clk_hw_register_gate.

v5:
-patch-2 Kconfig: add select AUXILIARY_BUS
-reset-aspeed: #define to_aspeed_reset(p) turn into static inline function.
-reset-aspeed: modify spin_lock_irqsave to guard(spinlock_irqsave)
-reset-aspeed: remove unnecessary parentheses.
-clk-ast2700: use <linux/units.h> and refrain from define clk

v4:
-yaml: keep size-cells=<1>.
-merge clk,reset dt binding header with yaml the same patch.
-rename clk,reset dt binding header to aspeed,ast2700-scu.h
-reset-aspeed: update tables tabs sapces to consistent spaces.
-reset-aspeed: remove no use dev_set_drvdata.
-clk-ast2700: modify reset_name to const int scu in struct clk_data.
-clk-ast2700: use scu number in clk_data generate reset_name for reset
 driver register.
-clk-ast2700: fix pll number mix up scu0,scu1.
-clk-ast2700: update dt-binding clock include file.

v3:
-yaml: v2 missing send yaml patch, v3 add.
-yaml: drop 64bits address example.
-yaml: add discription about soc0 and soc1
-dt-bindings: remove (), *_NUMS, reserved.
-dt-bindings: remove dulipated define number.
-dt-bindings: merge clk and reset to be one patch.
-reset-aspeed: add auxiliary device for reset driver.
-clk-ast2700: modify reset to be auxiliary add.
-clk-ast2700: modify to be platform driver.
-clk-ast2700: modify each clk to const clk array.

v2:
-yaml: drop 64bits address example.
-yaml: add discription about soc0 and soc1
-dt-bindings: remove (), *_NUMS, reserved.
-dt-bindings: remove dulipated define number
-clk-ast2700: drop WARN_ON, weird comment.

Ryan Chen (3):
  dt-bindings: mfd: aspeed: support for AST2700
  reset: aspeed: register AST2700 reset auxiliary bus device
  clk: aspeed: add AST2700 clock driver.

 .../bindings/mfd/aspeed,ast2x00-scu.yaml      |    8 +-
 drivers/clk/Kconfig                           |    8 +
 drivers/clk/Makefile                          |    1 +
 drivers/clk/clk-ast2700.c                     | 1513 +++++++++++++++++
 drivers/reset/Kconfig                         |    7 +
 drivers/reset/Makefile                        |    1 +
 drivers/reset/reset-aspeed.c                  |  302 ++++
 .../dt-bindings/clock/aspeed,ast2700-scu.h    |  163 ++
 .../dt-bindings/reset/aspeed,ast2700-scu.h    |  124 ++
 include/soc/aspeed/reset-aspeed.h             |   21 +
 10 files changed, 2147 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/clk-ast2700.c
 create mode 100644 drivers/reset/reset-aspeed.c
 create mode 100644 include/dt-bindings/clock/aspeed,ast2700-scu.h
 create mode 100644 include/dt-bindings/reset/aspeed,ast2700-scu.h
 create mode 100644 include/soc/aspeed/reset-aspeed.h

-- 
2.34.1



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

* [PATCH v7 1/3] dt-bindings: mfd: aspeed: support for AST2700
  2024-10-28  5:30 [PATCH v7 0/3] [PATCH v6 0/3] Add support for AST2700 clk driver Ryan Chen
@ 2024-10-28  5:30 ` Ryan Chen
  2024-10-28  5:30 ` [PATCH v7 2/3] reset: aspeed: register AST2700 reset auxiliary bus device Ryan Chen
  2024-10-28  5:30 ` [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver Ryan Chen
  2 siblings, 0 replies; 14+ messages in thread
From: Ryan Chen @ 2024-10-28  5:30 UTC (permalink / raw)
  To: ryan_chen, lee, robh, krzk+dt, conor+dt, joel, andrew, mturquette,
	sboyd, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, linux-clk, dmitry.baryshkov
  Cc: Krzysztof Kozlowski

Add reset, clk dt bindings headers, and update compatible
support for AST2700 clk, silicon-id in yaml.

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
---
 .../bindings/mfd/aspeed,ast2x00-scu.yaml      |   8 +-
 .../dt-bindings/clock/aspeed,ast2700-scu.h    | 163 ++++++++++++++++++
 .../dt-bindings/reset/aspeed,ast2700-scu.h    | 124 +++++++++++++
 3 files changed, 294 insertions(+), 1 deletion(-)
 create mode 100644 include/dt-bindings/clock/aspeed,ast2700-scu.h
 create mode 100644 include/dt-bindings/reset/aspeed,ast2700-scu.h

diff --git a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
index 86ee69c0f45b..c800d5e53b65 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
+++ b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
@@ -9,6 +9,8 @@ title: Aspeed System Control Unit
 description:
   The Aspeed System Control Unit manages the global behaviour of the SoC,
   configuring elements such as clocks, pinmux, and reset.
+  In AST2700 SOC which has two soc connection, each soc have its own scu
+  register control, ast2700-scu0 for soc0, ast2700-scu1 for soc1.
 
 maintainers:
   - Joel Stanley <joel@jms.id.au>
@@ -21,6 +23,8 @@ properties:
           - aspeed,ast2400-scu
           - aspeed,ast2500-scu
           - aspeed,ast2600-scu
+          - aspeed,ast2700-scu0
+          - aspeed,ast2700-scu1
       - const: syscon
       - const: simple-mfd
 
@@ -30,7 +34,8 @@ properties:
   ranges: true
 
   '#address-cells':
-    const: 1
+    minimum: 1
+    maximum: 2
 
   '#size-cells':
     const: 1
@@ -76,6 +81,7 @@ patternProperties:
               - aspeed,ast2400-silicon-id
               - aspeed,ast2500-silicon-id
               - aspeed,ast2600-silicon-id
+              - aspeed,ast2700-silicon-id
           - const: aspeed,silicon-id
 
       reg:
diff --git a/include/dt-bindings/clock/aspeed,ast2700-scu.h b/include/dt-bindings/clock/aspeed,ast2700-scu.h
new file mode 100644
index 000000000000..63021af3caf5
--- /dev/null
+++ b/include/dt-bindings/clock/aspeed,ast2700-scu.h
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Device Tree binding constants for AST2700 clock controller.
+ *
+ * Copyright (c) 2024 Aspeed Technology Inc.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_AST2700_H
+#define __DT_BINDINGS_CLOCK_AST2700_H
+
+/* SOC0 clk */
+#define SCU0_CLKIN		0
+#define SCU0_CLK_24M		1
+#define SCU0_CLK_192M		2
+#define SCU0_CLK_UART		3
+#define SCU0_CLK_UART_DIV13	3
+#define SCU0_CLK_PSP		4
+#define SCU0_CLK_HPLL		5
+#define SCU0_CLK_HPLL_DIV2	6
+#define SCU0_CLK_HPLL_DIV4	7
+#define SCU0_CLK_HPLL_DIV_AHB	8
+#define SCU0_CLK_DPLL		9
+#define SCU0_CLK_MPLL		10
+#define SCU0_CLK_MPLL_DIV2	11
+#define SCU0_CLK_MPLL_DIV4	12
+#define SCU0_CLK_MPLL_DIV8	13
+#define SCU0_CLK_MPLL_DIV_AHB	14
+#define SCU0_CLK_D0		15
+#define SCU0_CLK_D1		16
+#define SCU0_CLK_CRT0		17
+#define SCU0_CLK_CRT1		18
+#define SCU0_CLK_MPHY		19
+#define SCU0_CLK_AXI0		20
+#define SCU0_CLK_AXI1		21
+#define SCU0_CLK_AHB		22
+#define SCU0_CLK_APB		23
+#define SCU0_CLK_UART4		24
+#define SCU0_CLK_EMMCMUX	25
+#define SCU0_CLK_EMMC		26
+#define SCU0_CLK_U2PHY_CLK12M	27
+#define SCU0_CLK_U2PHY_REFCLK	28
+
+/* SOC0 clk-gate */
+#define SCU0_CLK_GATE_MCLK	29
+#define SCU0_CLK_GATE_ECLK	30
+#define SCU0_CLK_GATE_2DCLK	31
+#define SCU0_CLK_GATE_VCLK	32
+#define SCU0_CLK_GATE_BCLK	33
+#define SCU0_CLK_GATE_VGA0CLK	34
+#define SCU0_CLK_GATE_REFCLK	35
+#define SCU0_CLK_GATE_PORTBUSB2CLK	36
+#define SCU0_CLK_GATE_UHCICLK	37
+#define SCU0_CLK_GATE_VGA1CLK	38
+#define SCU0_CLK_GATE_DDRPHYCLK	39
+#define SCU0_CLK_GATE_E2M0CLK	40
+#define SCU0_CLK_GATE_HACCLK	41
+#define SCU0_CLK_GATE_PORTAUSB2CLK	42
+#define SCU0_CLK_GATE_UART4CLK	43
+#define SCU0_CLK_GATE_SLICLK	44
+#define SCU0_CLK_GATE_DACCLK	45
+#define SCU0_CLK_GATE_DP	46
+#define SCU0_CLK_GATE_E2M1CLK	47
+#define SCU0_CLK_GATE_CRT0CLK	48
+#define SCU0_CLK_GATE_CRT1CLK	49
+#define SCU0_CLK_GATE_ECDSACLK	50
+#define SCU0_CLK_GATE_RSACLK	51
+#define SCU0_CLK_GATE_RVAS0CLK	52
+#define SCU0_CLK_GATE_UFSCLK	53
+#define SCU0_CLK_GATE_EMMCCLK	54
+#define SCU0_CLK_GATE_RVAS1CLK	55
+
+/* SOC1 clk */
+#define SCU1_CLKIN		0
+#define SCU1_CLK_HPLL		1
+#define SCU1_CLK_APLL		2
+#define SCU1_CLK_APLL_DIV2	3
+#define SCU1_CLK_APLL_DIV4	4
+#define SCU1_CLK_DPLL		5
+#define SCU1_CLK_UXCLK		6
+#define SCU1_CLK_HUXCLK		7
+#define SCU1_CLK_UARTX		8
+#define SCU1_CLK_HUARTX		9
+#define SCU1_CLK_AHB		10
+#define SCU1_CLK_APB		11
+#define SCU1_CLK_UART0		12
+#define SCU1_CLK_UART1		13
+#define SCU1_CLK_UART2		14
+#define SCU1_CLK_UART3		15
+#define SCU1_CLK_UART5		16
+#define SCU1_CLK_UART6		17
+#define SCU1_CLK_UART7		18
+#define SCU1_CLK_UART8		19
+#define SCU1_CLK_UART9		20
+#define SCU1_CLK_UART10		21
+#define SCU1_CLK_UART11		22
+#define SCU1_CLK_UART12		23
+#define SCU1_CLK_UART13		24
+#define SCU1_CLK_UART14		25
+#define SCU1_CLK_APLL_DIVN	26
+#define SCU1_CLK_SDMUX		27
+#define SCU1_CLK_SDCLK		28
+#define SCU1_CLK_RMII		29
+#define SCU1_CLK_RGMII		30
+#define SCU1_CLK_MACHCLK	31
+#define SCU1_CLK_MAC0RCLK	32
+#define SCU1_CLK_MAC1RCLK	33
+#define SCU1_CLK_CAN		34
+
+/* SOC1 clk gate */
+#define SCU1_CLK_GATE_LCLK0		35
+#define SCU1_CLK_GATE_LCLK1		36
+#define SCU1_CLK_GATE_ESPI0CLK		37
+#define SCU1_CLK_GATE_ESPI1CLK		38
+#define SCU1_CLK_GATE_SDCLK		39
+#define SCU1_CLK_GATE_IPEREFCLK		40
+#define SCU1_CLK_GATE_REFCLK		41
+#define SCU1_CLK_GATE_LPCHCLK		42
+#define SCU1_CLK_GATE_MAC0CLK		43
+#define SCU1_CLK_GATE_MAC1CLK		44
+#define SCU1_CLK_GATE_MAC2CLK		45
+#define SCU1_CLK_GATE_UART0CLK		46
+#define SCU1_CLK_GATE_UART1CLK		47
+#define SCU1_CLK_GATE_UART2CLK		48
+#define SCU1_CLK_GATE_UART3CLK		49
+#define SCU1_CLK_GATE_I2CCLK		50
+#define SCU1_CLK_GATE_I3C0CLK		51
+#define SCU1_CLK_GATE_I3C1CLK		52
+#define SCU1_CLK_GATE_I3C2CLK		53
+#define SCU1_CLK_GATE_I3C3CLK		54
+#define SCU1_CLK_GATE_I3C4CLK		55
+#define SCU1_CLK_GATE_I3C5CLK		56
+#define SCU1_CLK_GATE_I3C6CLK		57
+#define SCU1_CLK_GATE_I3C7CLK		58
+#define SCU1_CLK_GATE_I3C8CLK		59
+#define SCU1_CLK_GATE_I3C9CLK		60
+#define SCU1_CLK_GATE_I3C10CLK		61
+#define SCU1_CLK_GATE_I3C11CLK		62
+#define SCU1_CLK_GATE_I3C12CLK		63
+#define SCU1_CLK_GATE_I3C13CLK		64
+#define SCU1_CLK_GATE_I3C14CLK		65
+#define SCU1_CLK_GATE_I3C15CLK		66
+#define SCU1_CLK_GATE_UART5CLK		67
+#define SCU1_CLK_GATE_UART6CLK		68
+#define SCU1_CLK_GATE_UART7CLK		69
+#define SCU1_CLK_GATE_UART8CLK		70
+#define SCU1_CLK_GATE_UART9CLK		71
+#define SCU1_CLK_GATE_UART10CLK		72
+#define SCU1_CLK_GATE_UART11CLK		73
+#define SCU1_CLK_GATE_UART12CLK		74
+#define SCU1_CLK_GATE_FSICLK		75
+#define SCU1_CLK_GATE_LTPIPHYCLK	76
+#define SCU1_CLK_GATE_LTPICLK		77
+#define SCU1_CLK_GATE_VGALCLK		78
+#define SCU1_CLK_GATE_UHCICLK		79
+#define SCU1_CLK_GATE_CANCLK		80
+#define SCU1_CLK_GATE_PCICLK		81
+#define SCU1_CLK_GATE_SLICLK		82
+#define SCU1_CLK_GATE_E2MCLK		83
+#define SCU1_CLK_GATE_PORTCUSB2CLK	84
+#define SCU1_CLK_GATE_PORTDUSB2CLK	85
+#define SCU1_CLK_GATE_LTPI1TXCLK	86
+
+#endif
diff --git a/include/dt-bindings/reset/aspeed,ast2700-scu.h b/include/dt-bindings/reset/aspeed,ast2700-scu.h
new file mode 100644
index 000000000000..d53c719b7a66
--- /dev/null
+++ b/include/dt-bindings/reset/aspeed,ast2700-scu.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Device Tree binding constants for AST2700 reset controller.
+ *
+ * Copyright (c) 2024 Aspeed Technology Inc.
+ */
+
+#ifndef _MACH_ASPEED_AST2700_RESET_H_
+#define _MACH_ASPEED_AST2700_RESET_H_
+
+/* SOC0 */
+#define SCU0_RESET_SDRAM	0
+#define SCU0_RESET_DDRPHY	1
+#define SCU0_RESET_RSA		2
+#define SCU0_RESET_SHA3		3
+#define SCU0_RESET_HACE		4
+#define SCU0_RESET_SOC		5
+#define SCU0_RESET_VIDEO	6
+#define SCU0_RESET_2D		7
+#define SCU0_RESET_PCIS		8
+#define SCU0_RESET_RVAS0	9
+#define SCU0_RESET_RVAS1	10
+#define SCU0_RESET_SM3		11
+#define SCU0_RESET_SM4		12
+#define SCU0_RESET_CRT0		13
+#define SCU0_RESET_ECC		14
+#define SCU0_RESET_DP_PCI	15
+#define SCU0_RESET_UFS		16
+#define SCU0_RESET_EMMC		17
+#define SCU0_RESET_PCIE1RST	18
+#define SCU0_RESET_PCIE1RSTOE	19
+#define SCU0_RESET_PCIE0RST	20
+#define SCU0_RESET_PCIE0RSTOE	21
+#define SCU0_RESET_JTAG		22
+#define SCU0_RESET_MCTP0	23
+#define SCU0_RESET_MCTP1	24
+#define SCU0_RESET_XDMA0	25
+#define SCU0_RESET_XDMA1	26
+#define SCU0_RESET_H2X1		27
+#define SCU0_RESET_DP		28
+#define SCU0_RESET_DP_MCU	29
+#define SCU0_RESET_SSP		30
+#define SCU0_RESET_H2X0		31
+#define SCU0_RESET_PORTA_VHUB	32
+#define SCU0_RESET_PORTA_PHY3	33
+#define SCU0_RESET_PORTA_XHCI	34
+#define SCU0_RESET_PORTB_VHUB	35
+#define SCU0_RESET_PORTB_PHY3	36
+#define SCU0_RESET_PORTB_XHCI	37
+#define SCU0_RESET_PORTA_VHUB_EHCI	38
+#define SCU0_RESET_PORTB_VHUB_EHCI	39
+#define SCU0_RESET_UHCI		40
+#define SCU0_RESET_TSP		41
+#define SCU0_RESET_E2M0		42
+#define SCU0_RESET_E2M1		43
+#define SCU0_RESET_VLINK	44
+
+/* SOC1 */
+#define SCU1_RESET_LPC0		0
+#define SCU1_RESET_LPC1		1
+#define SCU1_RESET_MII		2
+#define SCU1_RESET_PECI		3
+#define SCU1_RESET_PWM		4
+#define SCU1_RESET_MAC0		5
+#define SCU1_RESET_MAC1		6
+#define SCU1_RESET_MAC2		7
+#define SCU1_RESET_ADC		8
+#define SCU1_RESET_SD		9
+#define SCU1_RESET_ESPI0	10
+#define SCU1_RESET_ESPI1	11
+#define SCU1_RESET_JTAG1	12
+#define SCU1_RESET_SPI0		13
+#define SCU1_RESET_SPI1		14
+#define SCU1_RESET_SPI2		15
+#define SCU1_RESET_I3C0		16
+#define SCU1_RESET_I3C1		17
+#define SCU1_RESET_I3C2		18
+#define SCU1_RESET_I3C3		19
+#define SCU1_RESET_I3C4		20
+#define SCU1_RESET_I3C5		21
+#define SCU1_RESET_I3C6		22
+#define SCU1_RESET_I3C7		23
+#define SCU1_RESET_I3C8		24
+#define SCU1_RESET_I3C9		25
+#define SCU1_RESET_I3C10	26
+#define SCU1_RESET_I3C11	27
+#define SCU1_RESET_I3C12	28
+#define SCU1_RESET_I3C13	29
+#define SCU1_RESET_I3C14	30
+#define SCU1_RESET_I3C15	31
+#define SCU1_RESET_MCU0		32
+#define SCU1_RESET_MCU1		33
+#define SCU1_RESET_H2A_SPI1	34
+#define SCU1_RESET_H2A_SPI2	35
+#define SCU1_RESET_UART0	36
+#define SCU1_RESET_UART1	37
+#define SCU1_RESET_UART2	38
+#define SCU1_RESET_UART3	39
+#define SCU1_RESET_I2C_FILTER	40
+#define SCU1_RESET_CALIPTRA	41
+#define SCU1_RESET_XDMA		42
+#define SCU1_RESET_FSI		43
+#define SCU1_RESET_CAN		44
+#define SCU1_RESET_MCTP		45
+#define SCU1_RESET_I2C		46
+#define SCU1_RESET_UART6	47
+#define SCU1_RESET_UART7	48
+#define SCU1_RESET_UART8	49
+#define SCU1_RESET_UART9	50
+#define SCU1_RESET_LTPI0	51
+#define SCU1_RESET_VGAL		52
+#define SCU1_RESET_LTPI1	53
+#define SCU1_RESET_ACE		54
+#define SCU1_RESET_E2M		55
+#define SCU1_RESET_UHCI		56
+#define SCU1_RESET_PORTC_USB2UART	57
+#define SCU1_RESET_PORTC_VHUB_EHCI	58
+#define SCU1_RESET_PORTD_USB2UART	59
+#define SCU1_RESET_PORTD_VHUB_EHCI	60
+#define SCU1_RESET_H2X		61
+#define SCU1_RESET_I3CDMA	62
+#define SCU1_RESET_PCIE2RST	63
+
+#endif  /* _MACH_ASPEED_AST2700_RESET_H_ */
-- 
2.34.1



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

* [PATCH v7 2/3] reset: aspeed: register AST2700 reset auxiliary bus device
  2024-10-28  5:30 [PATCH v7 0/3] [PATCH v6 0/3] Add support for AST2700 clk driver Ryan Chen
  2024-10-28  5:30 ` [PATCH v7 1/3] dt-bindings: mfd: aspeed: support for AST2700 Ryan Chen
@ 2024-10-28  5:30 ` Ryan Chen
  2024-10-28  5:30 ` [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver Ryan Chen
  2 siblings, 0 replies; 14+ messages in thread
From: Ryan Chen @ 2024-10-28  5:30 UTC (permalink / raw)
  To: ryan_chen, lee, robh, krzk+dt, conor+dt, joel, andrew, mturquette,
	sboyd, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, linux-clk, dmitry.baryshkov

The AST2700 reset driver is registered as an auxiliary device
due to reset and clock controller share the same register region.

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/reset/Kconfig             |   7 +
 drivers/reset/Makefile            |   1 +
 drivers/reset/reset-aspeed.c      | 302 ++++++++++++++++++++++++++++++
 include/soc/aspeed/reset-aspeed.h |  21 +++
 4 files changed, 331 insertions(+)
 create mode 100644 drivers/reset/reset-aspeed.c
 create mode 100644 include/soc/aspeed/reset-aspeed.h

diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 67bce340a87e..71a3accea7cb 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -22,6 +22,13 @@ config RESET_A10SR
 	  This option enables support for the external reset functions for
 	  peripheral PHYs on the Altera Arria10 System Resource Chip.
 
+config RESET_ASPEED
+	tristate "ASPEED Reset Driver"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	select AUXILIARY_BUS
+	help
+	  This enables the reset controller driver for AST2700.
+
 config RESET_ATH79
 	bool "AR71xx Reset Driver" if COMPILE_TEST
 	default ATH79
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 27b0bbdfcc04..97482bb56416 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -5,6 +5,7 @@ obj-y += starfive/
 obj-y += sti/
 obj-y += tegra/
 obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
+obj-$(CONFIG_RESET_ASPEED) += reset-aspeed.o
 obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
 obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o
 obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o
diff --git a/drivers/reset/reset-aspeed.c b/drivers/reset/reset-aspeed.c
new file mode 100644
index 000000000000..2dc8478af7b0
--- /dev/null
+++ b/drivers/reset/reset-aspeed.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024 ASPEED Technology Inc.
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/reset/aspeed,ast2700-scu.h>
+#include <soc/aspeed/reset-aspeed.h>
+
+#define SCU0_RESET_CTRL1 0x200
+#define SCU0_RESET_CTRL2 0x220
+#define SCU1_RESET_CTRL1 0x200
+#define SCU1_RESET_CTRL2 0x220
+#define SCU1_PCIE3_CTRL 0x908
+
+struct ast2700_reset_signal {
+	bool dedicated_clr; /* dedicated reset clr offset */
+	u32 offset, bit;
+};
+
+struct aspeed_reset_info {
+	unsigned int nr_resets;
+	const struct ast2700_reset_signal *signal;
+};
+
+struct aspeed_reset {
+	struct reset_controller_dev rcdev;
+	struct aspeed_reset_info *info;
+	spinlock_t lock; /* Protect read-modify-write cycle */
+	void __iomem *base;
+};
+
+static const struct ast2700_reset_signal ast2700_reset0_signals[] = {
+	[SCU0_RESET_SDRAM] = { true, SCU0_RESET_CTRL1, BIT(0) },
+	[SCU0_RESET_DDRPHY] = { true, SCU0_RESET_CTRL1, BIT(1) },
+	[SCU0_RESET_RSA] = { true, SCU0_RESET_CTRL1, BIT(2) },
+	[SCU0_RESET_SHA3] = { true, SCU0_RESET_CTRL1, BIT(3) },
+	[SCU0_RESET_HACE] = { true, SCU0_RESET_CTRL1, BIT(4) },
+	[SCU0_RESET_SOC] = { true, SCU0_RESET_CTRL1, BIT(5) },
+	[SCU0_RESET_VIDEO] = { true, SCU0_RESET_CTRL1, BIT(6) },
+	[SCU0_RESET_2D] = { true, SCU0_RESET_CTRL1, BIT(7) },
+	[SCU0_RESET_PCIS] = { true, SCU0_RESET_CTRL1, BIT(8) },
+	[SCU0_RESET_RVAS0] = { true, SCU0_RESET_CTRL1, BIT(9) },
+	[SCU0_RESET_RVAS1] = { true, SCU0_RESET_CTRL1, BIT(10) },
+	[SCU0_RESET_SM3] = { true, SCU0_RESET_CTRL1, BIT(11) },
+	[SCU0_RESET_SM4] = { true, SCU0_RESET_CTRL1, BIT(12) },
+	[SCU0_RESET_CRT0] = { true, SCU0_RESET_CTRL1, BIT(13) },
+	[SCU0_RESET_ECC] = { true, SCU0_RESET_CTRL1, BIT(14) },
+	[SCU0_RESET_DP_PCI] = { true, SCU0_RESET_CTRL1, BIT(15) },
+	[SCU0_RESET_UFS] = { true, SCU0_RESET_CTRL1, BIT(16) },
+	[SCU0_RESET_EMMC] = { true, SCU0_RESET_CTRL1, BIT(17) },
+	[SCU0_RESET_PCIE1RST] = { true, SCU0_RESET_CTRL1, BIT(18) },
+	[SCU0_RESET_PCIE1RSTOE] = { true, SCU0_RESET_CTRL1, BIT(19) },
+	[SCU0_RESET_PCIE0RST] = { true, SCU0_RESET_CTRL1, BIT(20) },
+	[SCU0_RESET_PCIE0RSTOE] = { true, SCU0_RESET_CTRL1, BIT(21) },
+	[SCU0_RESET_JTAG] = { true, SCU0_RESET_CTRL1, BIT(22) },
+	[SCU0_RESET_MCTP0] = { true, SCU0_RESET_CTRL1, BIT(23) },
+	[SCU0_RESET_MCTP1] = { true, SCU0_RESET_CTRL1, BIT(24) },
+	[SCU0_RESET_XDMA0] = { true, SCU0_RESET_CTRL1, BIT(25) },
+	[SCU0_RESET_XDMA1] = { true, SCU0_RESET_CTRL1, BIT(26) },
+	[SCU0_RESET_H2X1] = { true, SCU0_RESET_CTRL1, BIT(27) },
+	[SCU0_RESET_DP] = { true, SCU0_RESET_CTRL1, BIT(28) },
+	[SCU0_RESET_DP_MCU] = { true, SCU0_RESET_CTRL1, BIT(29) },
+	[SCU0_RESET_SSP] = { true, SCU0_RESET_CTRL1, BIT(30) },
+	[SCU0_RESET_H2X0] = { true, SCU0_RESET_CTRL1, BIT(31) },
+	[SCU0_RESET_PORTA_VHUB] = { true, SCU0_RESET_CTRL2, BIT(0) },
+	[SCU0_RESET_PORTA_PHY3] = { true, SCU0_RESET_CTRL2, BIT(1) },
+	[SCU0_RESET_PORTA_XHCI] = { true, SCU0_RESET_CTRL2, BIT(2) },
+	[SCU0_RESET_PORTB_VHUB] = { true, SCU0_RESET_CTRL2, BIT(3) },
+	[SCU0_RESET_PORTB_PHY3] = { true, SCU0_RESET_CTRL2, BIT(4) },
+	[SCU0_RESET_PORTB_XHCI] = { true, SCU0_RESET_CTRL2, BIT(5) },
+	[SCU0_RESET_PORTA_VHUB_EHCI] = { true, SCU0_RESET_CTRL2, BIT(6) },
+	[SCU0_RESET_PORTB_VHUB_EHCI] = { true, SCU0_RESET_CTRL2, BIT(7) },
+	[SCU0_RESET_UHCI] = { true, SCU0_RESET_CTRL2, BIT(8) },
+	[SCU0_RESET_TSP] = { true, SCU0_RESET_CTRL2, BIT(9) },
+	[SCU0_RESET_E2M0] = { true, SCU0_RESET_CTRL2, BIT(10) },
+	[SCU0_RESET_E2M1] = { true, SCU0_RESET_CTRL2, BIT(11) },
+	[SCU0_RESET_VLINK] = { true, SCU0_RESET_CTRL2, BIT(12) },
+};
+
+static const struct ast2700_reset_signal ast2700_reset1_signals[] = {
+	[SCU1_RESET_LPC0] = { true, SCU1_RESET_CTRL1, BIT(0) },
+	[SCU1_RESET_LPC1] = { true, SCU1_RESET_CTRL1, BIT(1) },
+	[SCU1_RESET_MII] = { true, SCU1_RESET_CTRL1, BIT(2) },
+	[SCU1_RESET_PECI] = { true, SCU1_RESET_CTRL1, BIT(3) },
+	[SCU1_RESET_PWM] = { true, SCU1_RESET_CTRL1, BIT(4) },
+	[SCU1_RESET_MAC0] = { true, SCU1_RESET_CTRL1, BIT(5) },
+	[SCU1_RESET_MAC1] = { true, SCU1_RESET_CTRL1, BIT(6) },
+	[SCU1_RESET_MAC2] = { true, SCU1_RESET_CTRL1, BIT(7) },
+	[SCU1_RESET_ADC] = { true, SCU1_RESET_CTRL1, BIT(8) },
+	[SCU1_RESET_SD] = { true, SCU1_RESET_CTRL1, BIT(9) },
+	[SCU1_RESET_ESPI0] = { true, SCU1_RESET_CTRL1, BIT(10) },
+	[SCU1_RESET_ESPI1] = { true, SCU1_RESET_CTRL1, BIT(11) },
+	[SCU1_RESET_JTAG1] = { true, SCU1_RESET_CTRL1, BIT(12) },
+	[SCU1_RESET_SPI0] = { true, SCU1_RESET_CTRL1, BIT(13) },
+	[SCU1_RESET_SPI1] = { true, SCU1_RESET_CTRL1, BIT(14) },
+	[SCU1_RESET_SPI2] = { true, SCU1_RESET_CTRL1, BIT(15) },
+	[SCU1_RESET_I3C0] = { true, SCU1_RESET_CTRL1, BIT(16) },
+	[SCU1_RESET_I3C1] = { true, SCU1_RESET_CTRL1, BIT(17) },
+	[SCU1_RESET_I3C2] = { true, SCU1_RESET_CTRL1, BIT(18) },
+	[SCU1_RESET_I3C3] = { true, SCU1_RESET_CTRL1, BIT(19) },
+	[SCU1_RESET_I3C4] = { true, SCU1_RESET_CTRL1, BIT(20) },
+	[SCU1_RESET_I3C5] = { true, SCU1_RESET_CTRL1, BIT(21) },
+	[SCU1_RESET_I3C6] = { true, SCU1_RESET_CTRL1, BIT(22) },
+	[SCU1_RESET_I3C7] = { true, SCU1_RESET_CTRL1, BIT(23) },
+	[SCU1_RESET_I3C8] = { true, SCU1_RESET_CTRL1, BIT(24) },
+	[SCU1_RESET_I3C9] = { true, SCU1_RESET_CTRL1, BIT(25) },
+	[SCU1_RESET_I3C10] = { true, SCU1_RESET_CTRL1, BIT(26) },
+	[SCU1_RESET_I3C11] = { true, SCU1_RESET_CTRL1, BIT(27) },
+	[SCU1_RESET_I3C12] = { true, SCU1_RESET_CTRL1, BIT(28) },
+	[SCU1_RESET_I3C13] = { true, SCU1_RESET_CTRL1, BIT(29) },
+	[SCU1_RESET_I3C14] = { true, SCU1_RESET_CTRL1, BIT(30) },
+	[SCU1_RESET_I3C15] = { true, SCU1_RESET_CTRL1, BIT(31) },
+	[SCU1_RESET_MCU0] = { true, SCU1_RESET_CTRL2, BIT(0) },
+	[SCU1_RESET_MCU1] = { true, SCU1_RESET_CTRL2, BIT(1) },
+	[SCU1_RESET_H2A_SPI1] = { true, SCU1_RESET_CTRL2, BIT(2) },
+	[SCU1_RESET_H2A_SPI2] = { true, SCU1_RESET_CTRL2, BIT(3) },
+	[SCU1_RESET_UART0] = { true, SCU1_RESET_CTRL2, BIT(4) },
+	[SCU1_RESET_UART1] = { true, SCU1_RESET_CTRL2, BIT(5) },
+	[SCU1_RESET_UART2] = { true, SCU1_RESET_CTRL2, BIT(6) },
+	[SCU1_RESET_UART3] = { true, SCU1_RESET_CTRL2, BIT(7) },
+	[SCU1_RESET_I2C_FILTER] = { true, SCU1_RESET_CTRL2, BIT(8) },
+	[SCU1_RESET_CALIPTRA] = { true, SCU1_RESET_CTRL2, BIT(9) },
+	[SCU1_RESET_XDMA] = { true, SCU1_RESET_CTRL2, BIT(10) },
+	[SCU1_RESET_FSI] = { true, SCU1_RESET_CTRL2, BIT(12) },
+	[SCU1_RESET_CAN] = { true, SCU1_RESET_CTRL2, BIT(13) },
+	[SCU1_RESET_MCTP] = { true, SCU1_RESET_CTRL2, BIT(14) },
+	[SCU1_RESET_I2C] = { true, SCU1_RESET_CTRL2, BIT(15) },
+	[SCU1_RESET_UART6] = { true, SCU1_RESET_CTRL2, BIT(16) },
+	[SCU1_RESET_UART7] = { true, SCU1_RESET_CTRL2, BIT(17) },
+	[SCU1_RESET_UART8] = { true, SCU1_RESET_CTRL2, BIT(18) },
+	[SCU1_RESET_UART9] = { true, SCU1_RESET_CTRL2, BIT(19) },
+	[SCU1_RESET_LTPI0] = { true, SCU1_RESET_CTRL2, BIT(20) },
+	[SCU1_RESET_VGAL] = { true, SCU1_RESET_CTRL2, BIT(21) },
+	[SCU1_RESET_LTPI1] = { true, SCU1_RESET_CTRL2, BIT(22) },
+	[SCU1_RESET_ACE] = { true, SCU1_RESET_CTRL2, BIT(23) },
+	[SCU1_RESET_E2M] = { true, SCU1_RESET_CTRL2, BIT(24) },
+	[SCU1_RESET_UHCI] = { true, SCU1_RESET_CTRL2, BIT(25) },
+	[SCU1_RESET_PORTC_USB2UART] = { true, SCU1_RESET_CTRL2, BIT(26) },
+	[SCU1_RESET_PORTC_VHUB_EHCI] = { true, SCU1_RESET_CTRL2, BIT(27) },
+	[SCU1_RESET_PORTD_USB2UART] = { true, SCU1_RESET_CTRL2, BIT(28) },
+	[SCU1_RESET_PORTD_VHUB_EHCI] = { true, SCU1_RESET_CTRL2, BIT(29) },
+	[SCU1_RESET_H2X] = { true, SCU1_RESET_CTRL2, BIT(30) },
+	[SCU1_RESET_I3CDMA] = { true, SCU1_RESET_CTRL2, BIT(31) },
+	[SCU1_RESET_PCIE2RST] = { false, SCU1_PCIE3_CTRL, BIT(0) },
+};
+
+static inline struct aspeed_reset *to_aspeed_reset(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct aspeed_reset, rcdev);
+}
+
+static int aspeed_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	struct aspeed_reset *rc = to_aspeed_reset(rcdev);
+	void __iomem *reg_offset = rc->base + rc->info->signal[id].offset;
+
+	if (rc->info->signal[id].dedicated_clr) {
+		writel(rc->info->signal[id].bit, reg_offset);
+	} else {
+		guard(spinlock_irqsave)(&rc->lock);
+		writel(readl(reg_offset) & ~rc->info->signal[id].bit, reg_offset);
+	}
+
+	return 0;
+}
+
+static int aspeed_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	struct aspeed_reset *rc = to_aspeed_reset(rcdev);
+	void __iomem *reg_offset = rc->base + rc->info->signal[id].offset;
+
+	if (rc->info->signal[id].dedicated_clr) {
+		writel(rc->info->signal[id].bit, reg_offset + 0x04);
+	} else {
+		guard(spinlock_irqsave)(&rc->lock);
+		writel(readl(reg_offset) | rc->info->signal[id].bit, reg_offset);
+	}
+
+	return 0;
+}
+
+static int aspeed_reset_status(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	struct aspeed_reset *rc = to_aspeed_reset(rcdev);
+	void __iomem *reg_offset = rc->base + rc->info->signal[id].offset;
+
+	return (readl(reg_offset) & rc->info->signal[id].bit) ? 1 : 0;
+}
+
+static const struct reset_control_ops aspeed_reset_ops = {
+	.assert = aspeed_reset_assert,
+	.deassert = aspeed_reset_deassert,
+	.status = aspeed_reset_status,
+};
+
+static int aspeed_reset_probe(struct auxiliary_device *adev,
+			      const struct auxiliary_device_id *id)
+{
+	struct aspeed_reset *reset;
+	struct device *dev = &adev->dev;
+
+	reset = devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL);
+	if (!reset)
+		return -ENOMEM;
+
+	spin_lock_init(&reset->lock);
+
+	reset->info = (struct aspeed_reset_info *)id->driver_data;
+	reset->rcdev.owner = THIS_MODULE;
+	reset->rcdev.nr_resets = reset->info->nr_resets;
+	reset->rcdev.ops = &aspeed_reset_ops;
+	reset->rcdev.of_node = dev->parent->of_node;
+	reset->rcdev.dev = dev;
+	reset->rcdev.of_reset_n_cells = 1;
+	reset->base = (void __iomem *)adev->dev.platform_data;
+
+	return devm_reset_controller_register(dev, &reset->rcdev);
+}
+
+static void aspeed_reset_unregister_adev(void *_adev)
+{
+	struct auxiliary_device *adev = _adev;
+
+	auxiliary_device_delete(adev);
+	auxiliary_device_uninit(adev);
+}
+
+static void aspeed_reset_adev_release(struct device *dev)
+{
+	struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+	kfree(adev);
+}
+
+int aspeed_reset_controller_register(struct device *clk_dev, void __iomem *base,
+				     const char *adev_name)
+{
+	struct auxiliary_device *adev;
+	int ret;
+
+	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+	if (!adev)
+		return -ENOMEM;
+
+	adev->name = adev_name;
+	adev->dev.parent = clk_dev;
+	adev->dev.release = aspeed_reset_adev_release;
+	adev->id = 666u;
+
+	ret = auxiliary_device_init(adev);
+	if (ret) {
+		kfree(adev);
+		return ret;
+	}
+
+	ret = auxiliary_device_add(adev);
+	if (ret) {
+		auxiliary_device_uninit(adev);
+		return ret;
+	}
+
+	adev->dev.platform_data = (__force void *)base;
+
+	return devm_add_action_or_reset(clk_dev, aspeed_reset_unregister_adev, adev);
+}
+EXPORT_SYMBOL_GPL(aspeed_reset_controller_register);
+
+static const struct aspeed_reset_info ast2700_reset0_info = {
+	.nr_resets = ARRAY_SIZE(ast2700_reset0_signals),
+	.signal = ast2700_reset0_signals,
+};
+
+static const struct aspeed_reset_info ast2700_reset1_info = {
+	.nr_resets = ARRAY_SIZE(ast2700_reset1_signals),
+	.signal = ast2700_reset1_signals,
+};
+
+static const struct auxiliary_device_id aspeed_reset_ids[] = {
+	{ .name = "reset_aspeed.reset0", .driver_data = (kernel_ulong_t)&ast2700_reset0_info },
+	{ .name = "reset_aspeed.reset1", .driver_data = (kernel_ulong_t)&ast2700_reset1_info },
+	{ }
+};
+MODULE_DEVICE_TABLE(auxiliary, aspeed_reset_ids);
+
+static struct auxiliary_driver aspeed_reset_driver = {
+	.probe		= aspeed_reset_probe,
+	.id_table	= aspeed_reset_ids,
+};
+
+module_auxiliary_driver(aspeed_reset_driver);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
+MODULE_DESCRIPTION("ASPEED SoC Reset Controller Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/soc/aspeed/reset-aspeed.h b/include/soc/aspeed/reset-aspeed.h
new file mode 100644
index 000000000000..51a4d13fbe3d
--- /dev/null
+++ b/include/soc/aspeed/reset-aspeed.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 ASPEED Technology Inc.
+ * Author: Ryan Chen <ryan_chen@aspeedtech.com>
+ */
+
+#ifndef __RESET_ASPEED_H__
+#define __RESET_ASPEED_H__
+
+#if IS_ENABLED(CONFIG_RESET_ASPEED)
+int aspeed_reset_controller_register(struct device *clk_dev, void __iomem *base,
+				     const char *adev_name);
+#else
+static inline int aspeed_reset_controller_register(struct device *clk_dev, void __iomem *base,
+				     const char *adev_name)
+{
+	return -ENODEV;
+}
+#endif /* if IS_ENABLED(CONFIG_RESET_ASPEED) */
+
+#endif /* __RESET_ASPEED_H__ */
-- 
2.34.1



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

* [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-10-28  5:30 [PATCH v7 0/3] [PATCH v6 0/3] Add support for AST2700 clk driver Ryan Chen
  2024-10-28  5:30 ` [PATCH v7 1/3] dt-bindings: mfd: aspeed: support for AST2700 Ryan Chen
  2024-10-28  5:30 ` [PATCH v7 2/3] reset: aspeed: register AST2700 reset auxiliary bus device Ryan Chen
@ 2024-10-28  5:30 ` Ryan Chen
  2024-10-30 21:01   ` Stephen Boyd
                     ` (2 more replies)
  2 siblings, 3 replies; 14+ messages in thread
From: Ryan Chen @ 2024-10-28  5:30 UTC (permalink / raw)
  To: ryan_chen, lee, robh, krzk+dt, conor+dt, joel, andrew, mturquette,
	sboyd, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, linux-clk, dmitry.baryshkov

Add AST2700 clock controller driver and also use axiliary
device framework register the reset controller driver.
Due to clock and reset using the same register region.

Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
 drivers/clk/Kconfig       |    8 +
 drivers/clk/Makefile      |    1 +
 drivers/clk/clk-ast2700.c | 1513 +++++++++++++++++++++++++++++++++++++
 3 files changed, 1522 insertions(+)
 create mode 100644 drivers/clk/clk-ast2700.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 983ef4f36d8c..4cc35ecba1c0 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -269,6 +269,14 @@ config COMMON_CLK_ASPEED
 	  The G4 and G5 series, including the ast2400 and ast2500, are supported
 	  by this driver.
 
+config COMMON_CLK_AST2700
+	bool "Clock driver for AST2700 SoC"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	help
+	  This driver provides support for clock on AST2700 SoC.
+	  The driver is responsible for managing the various clocks required
+	  by the peripherals and cores within the AST2700.
+
 config COMMON_CLK_S2MPS11
 	tristate "Clock driver for S2MPS1X/S5M8767 MFD"
 	depends on MFD_SEC_CORE || COMPILE_TEST
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f793a16cad40..fe95203c3138 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_COMMON_CLK_FSL_SAI)	+= clk-fsl-sai.o
 obj-$(CONFIG_COMMON_CLK_GEMINI)		+= clk-gemini.o
 obj-$(CONFIG_COMMON_CLK_ASPEED)		+= clk-aspeed.o
 obj-$(CONFIG_MACH_ASPEED_G6)		+= clk-ast2600.o
+obj-$(CONFIG_COMMON_CLK_AST2700)	+= clk-ast2700.o
 obj-$(CONFIG_ARCH_HIGHBANK)		+= clk-highbank.o
 obj-$(CONFIG_CLK_HSDK)			+= clk-hsdk-pll.o
 obj-$(CONFIG_COMMON_CLK_K210)		+= clk-k210.o
diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c
new file mode 100644
index 000000000000..db9ee5031b7c
--- /dev/null
+++ b/drivers/clk/clk-ast2700.c
@@ -0,0 +1,1513 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 ASPEED Technology Inc.
+ * Author: Ryan Chen <ryan_chen@aspeedtech.com>
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/units.h>
+
+#include <dt-bindings/clock/aspeed,ast2700-scu.h>
+#include <soc/aspeed/reset-aspeed.h>
+
+#define SCU_CLK_12MHZ (12 * HZ_PER_MHZ)
+#define SCU_CLK_24MHZ (24 * HZ_PER_MHZ)
+#define SCU_CLK_25MHZ (25 * HZ_PER_MHZ)
+#define SCU_CLK_192MHZ (192 * HZ_PER_MHZ)
+
+/* SOC0 */
+#define SCU0_HWSTRAP1 0x010
+#define SCU0_CLK_STOP 0x240
+#define SCU0_CLK_SEL1 0x280
+#define SCU0_CLK_SEL2 0x284
+#define GET_USB_REFCLK_DIV(x) ((GENMASK(23, 20) & (x)) >> 20)
+#define UART_DIV13_EN BIT(30)
+#define SCU0_HPLL_PARAM 0x300
+#define SCU0_DPLL_PARAM 0x308
+#define SCU0_MPLL_PARAM 0x310
+#define SCU0_D0CLK_PARAM 0x320
+#define SCU0_D1CLK_PARAM 0x330
+#define SCU0_CRT0CLK_PARAM 0x340
+#define SCU0_CRT1CLK_PARAM 0x350
+#define SCU0_MPHYCLK_PARAM 0x360
+
+/* SOC1 */
+#define SCU1_REVISION_ID 0x0
+#define REVISION_ID GENMASK(23, 16)
+#define SCU1_CLK_STOP 0x240
+#define SCU1_CLK_STOP2 0x260
+#define SCU1_CLK_SEL1 0x280
+#define SCU1_CLK_SEL2 0x284
+#define UXCLK_MASK GENMASK(1, 0)
+#define HUXCLK_MASK GENMASK(4, 3)
+#define SCU1_HPLL_PARAM 0x300
+#define SCU1_APLL_PARAM 0x310
+#define SCU1_DPLL_PARAM 0x320
+#define SCU1_UXCLK_CTRL 0x330
+#define SCU1_HUXCLK_CTRL 0x334
+#define SCU1_MAC12_CLK_DLY 0x390
+#define SCU1_MAC12_CLK_DLY_100M 0x394
+#define SCU1_MAC12_CLK_DLY_10M 0x398
+
+enum {
+	CLK_MUX,
+	CLK_PLL,
+	CLK_GATE,
+	CLK_MISC,
+	CLK_FIXED,
+	CLK_DIVIDER,
+	CLK_UART_PLL,
+	CLK_DIV_TABLE,
+	CLK_FIXED_FACTOR,
+	CLK_GATE_ASPEED,
+};
+
+struct ast2700_clk_info {
+	const char *name;
+	const char * const *parent_names;
+	const struct clk_div_table *div_table;
+	unsigned long fixed_rate;
+	unsigned int mult;
+	unsigned int div;
+	u32 reg;
+	u32 flags;
+	u32 type;
+	u8 clk_idx;
+	u8 bit_shift;
+	u8 bit_width;
+	u8 num_parents;
+};
+
+struct ast2700_clk_data {
+	struct ast2700_clk_info const *clk_info;
+	unsigned int nr_clks;
+	const int scu;
+};
+
+struct ast2700_clk_ctrl {
+	const struct ast2700_clk_data *clk_data;
+	struct device *dev;
+	void __iomem *base;
+	spinlock_t lock; /* clk lock */
+};
+
+static const struct clk_div_table ast2700_rgmii_div_table[] = {
+	{ 0x0, 4 },
+	{ 0x1, 4 },
+	{ 0x2, 6 },
+	{ 0x3, 8 },
+	{ 0x4, 10 },
+	{ 0x5, 12 },
+	{ 0x6, 14 },
+	{ 0x7, 16 },
+	{ 0 }
+};
+
+static const struct clk_div_table ast2700_rmii_div_table[] = {
+	{ 0x0, 8 },
+	{ 0x1, 8 },
+	{ 0x2, 12 },
+	{ 0x3, 16 },
+	{ 0x4, 20 },
+	{ 0x5, 24 },
+	{ 0x6, 28 },
+	{ 0x7, 32 },
+	{ 0 }
+};
+
+static const struct clk_div_table ast2700_clk_div_table[] = {
+	{ 0x0, 2 },
+	{ 0x1, 2 },
+	{ 0x2, 3 },
+	{ 0x3, 4 },
+	{ 0x4, 5 },
+	{ 0x5, 6 },
+	{ 0x6, 7 },
+	{ 0x7, 8 },
+	{ 0 }
+};
+
+static const struct clk_div_table ast2700_clk_div_table2[] = {
+	{ 0x0, 2 },
+	{ 0x1, 4 },
+	{ 0x2, 6 },
+	{ 0x3, 8 },
+	{ 0x4, 10 },
+	{ 0x5, 12 },
+	{ 0x6, 14 },
+	{ 0x7, 16 },
+	{ 0 }
+};
+
+static const struct clk_div_table ast2700_clk_uart_div_table[] = {
+	{ 0x0, 1 },
+	{ 0x1, 13 },
+	{ 0 }
+};
+
+static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = {
+	[SCU0_CLKIN] = {
+		.type = CLK_FIXED,
+		.name = "soc0-clkin",
+		.fixed_rate = SCU_CLK_25MHZ,
+	},
+	[SCU0_CLK_24M] = {
+		.type = CLK_FIXED,
+		.name = "soc0-clk24Mhz",
+		.fixed_rate = SCU_CLK_24MHZ,
+	},
+	[SCU0_CLK_192M] = {
+		.type = CLK_FIXED,
+		.name = "soc0-clk192Mhz",
+		.fixed_rate = SCU_CLK_192MHZ,
+	},
+	[SCU0_CLK_HPLL] = {
+		.type = CLK_PLL,
+		.name = "soc0-hpll",
+		.parent_names = (const char *[]){ "soc0-clkin", },
+		.reg = SCU0_HPLL_PARAM,
+	},
+	[SCU0_CLK_HPLL_DIV2] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "soc0-hpll_div2",
+		.parent_names = (const char *[]){ "soc0-hpll", },
+		.mult = 1,
+		.div = 2,
+	},
+	[SCU0_CLK_HPLL_DIV4] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "soc0-hpll_div4",
+		.parent_names = (const char *[]){ "soc0-hpll", },
+		.mult = 1,
+		.div = 4,
+	},
+	[SCU0_CLK_HPLL_DIV_AHB] = {
+		.type = CLK_DIV_TABLE,
+		.name = "soc0-hpll_div_ahb",
+		.parent_names = (const char *[]){ "soc0-hpll", },
+		.reg = SCU0_HWSTRAP1,
+		.bit_shift = 5,
+		.bit_width = 2,
+		.div_table = ast2700_clk_div_table,
+	},
+	[SCU0_CLK_DPLL] = {
+		.type = CLK_PLL,
+		.name = "dpll",
+		.parent_names = (const char *[]){ "soc0-clkin", },
+		.reg = SCU0_DPLL_PARAM,
+	},
+	[SCU0_CLK_MPLL] = {
+		.type = CLK_PLL,
+		.name = "soc0-mpll",
+		.parent_names = (const char *[]){ "soc0-clkin", },
+		.reg = SCU0_MPLL_PARAM,
+	},
+	[SCU0_CLK_MPLL_DIV2] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "soc0-mpll_div2",
+		.parent_names = (const char *[]){ "soc0-mpll", },
+		.mult = 1,
+		.div = 2,
+	},
+	[SCU0_CLK_MPLL_DIV4] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "soc0-mpll_div4",
+		.parent_names = (const char *[]){ "soc0-mpll", },
+		.mult = 1,
+		.div = 4,
+	},
+	[SCU0_CLK_MPLL_DIV8] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "soc0-mpll_div8",
+		.parent_names = (const char *[]){ "soc0-mpll", },
+		.mult = 1,
+		.div = 8,
+	},
+	[SCU0_CLK_MPLL_DIV_AHB] = {
+		.type = CLK_DIV_TABLE,
+		.name = "soc0-mpll_div_ahb",
+		.parent_names = (const char *[]){ "soc0-mpll", },
+		.reg = SCU0_HWSTRAP1,
+		.bit_shift = 5,
+		.bit_width = 2,
+		.div_table = ast2700_clk_div_table,
+	},
+	[SCU0_CLK_D0] = {
+		.type = CLK_PLL,
+		.name = "d0clk",
+		.parent_names = (const char *[]){ "soc0-clkin", },
+		.reg = SCU0_D0CLK_PARAM,
+	},
+	[SCU0_CLK_D1] = {
+		.type = CLK_PLL,
+		.name = "d1clk",
+		.parent_names = (const char *[]){ "soc0-clkin", },
+		.reg = SCU0_D1CLK_PARAM,
+	},
+	[SCU0_CLK_CRT0] = {
+		.type = CLK_PLL,
+		.name = "crt0clk",
+		.parent_names = (const char *[]){ "soc0-clkin", },
+		.reg = SCU0_CRT0CLK_PARAM,
+	},
+	[SCU0_CLK_CRT1] = {
+		.type = CLK_PLL,
+		.name = "crt1clk",
+		.parent_names = (const char *[]){ "soc0-clkin", },
+		.reg = SCU0_CRT1CLK_PARAM,
+	},
+	[SCU0_CLK_MPHY] = {
+		.type = CLK_MISC,
+		.name = "mphyclk",
+		.parent_names = (const char *[]){ "soc0-hpll", },
+		.reg = SCU0_MPHYCLK_PARAM,
+	},
+	[SCU0_CLK_PSP] = {
+		.type = CLK_MUX,
+		.name = "pspclk",
+		.parent_names = (const char *[]){"soc0-mpll", "soc0-hpll", },
+		.num_parents = 2,
+		.reg = SCU0_HWSTRAP1,
+		.bit_shift = 4,
+		.bit_width = 1,
+	},
+	[SCU0_CLK_AXI0] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "axi0clk",
+		.parent_names = (const char *[]){"pspclk", },
+		.mult = 1,
+		.div = 2,
+	},
+	[SCU0_CLK_AHB] = {
+		.type = CLK_MUX,
+		.name = "soc0-ahb",
+		.parent_names = (const char *[]){"soc0-mpll_div_ahb", "soc0-hspll_div_ahb", },
+		.num_parents = 2,
+		.reg = SCU0_HWSTRAP1,
+		.bit_shift = 7,
+		.bit_width = 1,
+	},
+	[SCU0_CLK_AXI1] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "axi1clk",
+		.parent_names = (const char *[]){ "soc0-ahb", },
+		.mult = 1,
+		.div = 2,
+	},
+	[SCU0_CLK_APB] = {
+		.type = CLK_DIV_TABLE,
+		.name = "soc0-apb",
+		.parent_names = (const char *[]){ "axi0clk", },
+		.reg = SCU0_CLK_SEL1,
+		.bit_shift = 23,
+		.bit_width = 3,
+		.div_table = ast2700_clk_div_table2,
+	},
+	[SCU0_CLK_GATE_MCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "mclk-gate",
+		.parent_names = (const char *[]){ "soc0-mpll", },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 0,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_ECLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "eclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 1,
+	},
+	[SCU0_CLK_GATE_2DCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "gclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 2,
+	},
+	[SCU0_CLK_GATE_VCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "vclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 3,
+	},
+	[SCU0_CLK_GATE_BCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "bclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 4,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_VGA0CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "vga0clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 5,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_REFCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "soc0-refclk-gate",
+		.parent_names = (const char *[]){ "soc0-clkin", },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 6,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_U2PHY_REFCLK] = {
+		.type = CLK_MISC,
+		.name = "u2phy_refclk",
+		.parent_names = (const char *[]){ "soc0-mpll_div8", },
+		.reg = SCU0_CLK_SEL2,
+	},
+	[SCU0_CLK_U2PHY_CLK12M] = {
+		.type = CLK_FIXED,
+		.name = "u2phy_clk12m",
+		.parent_names = (const char *[]){  },
+		.fixed_rate = SCU_CLK_12MHZ,
+	},
+	[SCU0_CLK_GATE_PORTBUSB2CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "portb-usb2clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 7,
+	},
+	[SCU0_CLK_GATE_UHCICLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uhciclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 9,
+	},
+	[SCU0_CLK_GATE_VGA1CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "vga1clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 10,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_DDRPHYCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "ddrphy-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 11,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_E2M0CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "e2m0clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 12,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_HACCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "hacclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 13,
+	},
+	[SCU0_CLK_GATE_PORTAUSB2CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "porta-usb2clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 14,
+	},
+	[SCU0_CLK_UART] = {
+		.type = CLK_MUX,
+		.name = "soc0-uartclk",
+		.parent_names = (const char *[]){"soc0-clk24Mhz", "soc0-clk192Mhz", },
+		.num_parents = 2,
+		.reg = SCU0_CLK_SEL2,
+		.bit_shift = 14,
+		.bit_width = 1,
+	},
+	[SCU0_CLK_UART4] = {
+		.type = CLK_DIV_TABLE,
+		.name = "uart4clk",
+		.parent_names = (const char *[]){ "soc0-uartclk", },
+		.reg = SCU0_CLK_SEL2,
+		.bit_shift = 30,
+		.bit_width = 1,
+		.div_table = ast2700_clk_uart_div_table,
+	},
+	[SCU0_CLK_GATE_UART4CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart4clk-gate",
+		.parent_names = (const char *[]){"uart4clk" },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 15,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_SLICLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "soc0-sliclk-gate",
+		.parent_names = (const char *[]){	},
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 16,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_DACCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "dacclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 17,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_DP] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "dpclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 18,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_E2M1CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "e2m1clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 19,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU0_CLK_GATE_CRT0CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "crt0clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 20,
+	},
+	[SCU0_CLK_GATE_CRT1CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "crt1clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 21,
+	},
+	[SCU0_CLK_GATE_ECDSACLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "eccclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 23,
+	},
+	[SCU0_CLK_GATE_RSACLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "rsaclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 24,
+	},
+	[SCU0_CLK_GATE_RVAS0CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "rvasclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 25,
+	},
+	[SCU0_CLK_GATE_UFSCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "ufsclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 26,
+	},
+	[SCU0_CLK_EMMCMUX] = {
+		.type = CLK_MUX,
+		.name = "emmcsrc-mux",
+		.parent_names = (const char *[]){"soc0-mpll_div4", "soc0-hpll_div4", },
+		.num_parents = 2,
+		.reg = SCU0_CLK_SEL1,
+		.bit_shift = 11,
+		.bit_width = 1,
+	},
+	[SCU0_CLK_EMMC] = {
+		.type = CLK_DIV_TABLE,
+		.name = "emmcclk",
+		.parent_names = (const char *[]){ "emmcsrc-mux", },
+		.reg = SCU0_CLK_SEL1,
+		.bit_shift = 12,
+		.bit_width = 3,
+		.div_table = ast2700_clk_div_table2,
+	},
+	[SCU0_CLK_GATE_EMMCCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "emmcclk-gate",
+		.parent_names = (const char *[]){ "emmcclk", },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 27,
+	},
+	[SCU0_CLK_GATE_RVAS1CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "rvas2clk-gate",
+		.parent_names = (const char *[]){ "emmcclk", },
+		.reg = SCU0_CLK_STOP,
+		.clk_idx = 28,
+	},
+};
+
+static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = {
+	[SCU1_CLKIN] = {
+		.type = CLK_FIXED,
+		.name = "soc1-clkin",
+		.fixed_rate = SCU_CLK_25MHZ,
+	},
+	[SCU1_CLK_HPLL] = {
+		.type = CLK_PLL,
+		.name = "soc1-hpll",
+		.parent_names = (const char *[]){ "soc1-clkin", },
+		.reg = SCU1_HPLL_PARAM,
+	},
+	[SCU1_CLK_APLL] = {
+		.type = CLK_PLL,
+		.name = "soc1-apll",
+		.parent_names = (const char *[]){ "soc1-clkin", },
+		.reg = SCU1_APLL_PARAM,
+	},
+	[SCU1_CLK_APLL_DIV2] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "soc1-apll_div2",
+		.parent_names = (const char *[]){ "soc1-apll", },
+		.mult = 1,
+		.div = 2,
+	},
+	[SCU1_CLK_APLL_DIV4] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "soc1-apll_div4",
+		.parent_names = (const char *[]){ "soc1-apll", },
+		.mult = 1,
+		.div = 4,
+	},
+	[SCU1_CLK_DPLL] = {
+		.type = CLK_PLL,
+		.name = "soc1-dpll",
+		.parent_names = (const char *[]){ "soc1-clkin", },
+		.reg = SCU1_DPLL_PARAM,
+	},
+	[SCU1_CLK_UXCLK] = {
+		.type = CLK_MUX,
+		.name = "uxclk",
+		.parent_names = (const char *[]){ "soc1-apll_div4", "soc1-apll_div2",
+						 "soc1-apll", "soc1-hpll",},
+		.num_parents = 4,
+		.reg = SCU1_CLK_SEL2,
+		.bit_shift = 0,
+		.bit_width = 2,
+	},
+	[SCU1_CLK_UARTX] = {
+		.type = CLK_UART_PLL,
+		.name = "uartxclk",
+		.parent_names = (const char *[]){ "uxclk", },
+		.reg = SCU1_UXCLK_CTRL,
+	},
+	[SCU1_CLK_HUXCLK] = {
+		.type = CLK_MUX,
+		.name = "huxclk",
+		.parent_names = (const char *[]){"soc1-apll_div4", "soc1-apll_div2",
+						 "soc1-apll", "soc1-hpll",},
+		.num_parents = 4,
+		.reg = SCU1_CLK_SEL2,
+		.bit_shift = 3,
+		.bit_width = 2,
+	},
+	[SCU1_CLK_HUARTX] = {
+		.type = CLK_UART_PLL,
+		.name = "huartxclk",
+		.parent_names = (const char *[]){ "huxclk", },
+		.reg = SCU1_HUXCLK_CTRL,
+	},
+	[SCU1_CLK_AHB] = {
+		.type = CLK_DIV_TABLE,
+		.name = "soc1-ahb",
+		.parent_names = (const char *[]){"soc1-hpll", },
+		.reg = SCU1_CLK_SEL2,
+		.bit_shift = 20,
+		.bit_width = 3,
+		.div_table = ast2700_clk_div_table,
+	},
+	[SCU1_CLK_APB] = {
+		.type = CLK_DIV_TABLE,
+		.name = "soc1-apb",
+		.parent_names = (const char *[]){"soc1-hpll", },
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 18,
+		.bit_width = 3,
+		.div_table = ast2700_clk_div_table2,
+	},
+	[SCU1_CLK_RMII] = {
+		.type = CLK_DIV_TABLE,
+		.name = "rmii",
+		.parent_names = (const char *[]){"soc1-hpll", },
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 21,
+		.bit_width = 3,
+		.div_table = ast2700_rmii_div_table,
+	},
+	[SCU1_CLK_MAC0RCLK] = {
+		.type = CLK_GATE,
+		.name = "mac0rclk-gate",
+		.parent_names = (const char *[]){ "rmii", },
+		.reg = SCU1_MAC12_CLK_DLY,
+		.clk_idx = 29,
+	},
+	[SCU1_CLK_MAC1RCLK] = {
+		.type = CLK_GATE,
+		.name = "mac1rclk-gate",
+		.parent_names = (const char *[]){ "rmii", },
+		.reg = SCU1_MAC12_CLK_DLY,
+		.clk_idx = 30,
+	},
+	[SCU1_CLK_RGMII] = {
+		.type = CLK_DIV_TABLE,
+		.name = "rgmii",
+		.parent_names = (const char *[]){"soc1-hpll", },
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 25,
+		.bit_width = 3,
+		.div_table = ast2700_rgmii_div_table,
+	},
+	[SCU1_CLK_MACHCLK] = {
+		.type = CLK_DIV_TABLE,
+		.name = "machclk",
+		.parent_names = (const char *[]){"soc1-hpll", },
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 29,
+		.bit_width = 3,
+		.div_table = ast2700_clk_div_table,
+	},
+	[SCU1_CLK_GATE_LCLK0] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "lclk0-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 0,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_LCLK1] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "lclk1-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 1,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_ESPI0CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "espi0clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 2,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_ESPI1CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "espi1clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 3,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_APLL_DIVN] = {
+		.type = CLK_DIV_TABLE,
+		.name = "soc1-apll_divn",
+		.parent_names = (const char *[]){"soc1-apll", },
+		.reg = SCU1_CLK_SEL2,
+		.bit_shift = 8,
+		.bit_width = 3,
+		.div_table = ast2700_clk_div_table,
+	},
+	[SCU1_CLK_SDMUX] = {
+		.type = CLK_MUX,
+		.name = "sdclk-mux",
+		.parent_names = (const char *[]){ "soc1-hpll", "soc1-apll", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 13,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_SDCLK] = {
+		.type = CLK_DIV_TABLE,
+		.name = "sdclk",
+		.parent_names = (const char *[]){"sdclk-mux", },
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 14,
+		.bit_width = 3,
+		.div_table = ast2700_clk_div_table,
+	},
+	[SCU1_CLK_GATE_SDCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "sdclk-gate",
+		.parent_names = (const char *[]){"sdclk", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 4,
+	},
+	[SCU1_CLK_GATE_IPEREFCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "soc1-iperefclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 5,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_REFCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "soc1-refclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 6,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_LPCHCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "lpchclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 7,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_MAC0CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "mac0clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 8,
+	},
+	[SCU1_CLK_GATE_MAC1CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "mac1clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 9,
+	},
+	[SCU1_CLK_GATE_MAC2CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "mac2clk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 10,
+	},
+	[SCU1_CLK_UART0] = {
+		.type = CLK_MUX,
+		.name = "uart0clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 0,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART0CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart0clk-gate",
+		.parent_names = (const char *[]){ "uart0clk", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 11,
+	},
+	[SCU1_CLK_UART1] = {
+		.type = CLK_MUX,
+		.name = "uart1clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 1,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART1CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart1clk-gate",
+		.parent_names = (const char *[]){ "uart1clk", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 12,
+	},
+	[SCU1_CLK_UART2] = {
+		.type = CLK_MUX,
+		.name = "uart2clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 2,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART2CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart2clk-gate",
+		.parent_names = (const char *[]){ "uart2clk", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 13,
+	},
+	[SCU1_CLK_UART3] = {
+		.type = CLK_MUX,
+		.name = "uart3clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 3,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART3CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart3clk-gate",
+		.parent_names = (const char *[]){ "uart3clk", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 14,
+	},
+	[SCU1_CLK_GATE_I2CCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i2cclk-gate",
+		.parent_names = (const char *[]){	},
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 15,
+	},
+	[SCU1_CLK_GATE_I3C0CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c0clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 16,
+	},
+	[SCU1_CLK_GATE_I3C1CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c1clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 17,
+	},
+	[SCU1_CLK_GATE_I3C2CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c2clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 18,
+	},
+	[SCU1_CLK_GATE_I3C3CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c3clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 19,
+	},
+	[SCU1_CLK_GATE_I3C4CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c4clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 20,
+	},
+	[SCU1_CLK_GATE_I3C5CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c5clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 21,
+	},
+	[SCU1_CLK_GATE_I3C6CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c6clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 22,
+	},
+	[SCU1_CLK_GATE_I3C7CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c7clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 23,
+	},
+	[SCU1_CLK_GATE_I3C8CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c8clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 24,
+	},
+	[SCU1_CLK_GATE_I3C9CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c9clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 25,
+	},
+	[SCU1_CLK_GATE_I3C10CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c10clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 26,
+	},
+	[SCU1_CLK_GATE_I3C11CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c11clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 27,
+	},
+	[SCU1_CLK_GATE_I3C12CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c12clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 28,
+	},
+	[SCU1_CLK_GATE_I3C13CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c13clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 29,
+	},
+	[SCU1_CLK_GATE_I3C14CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c14clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 30,
+	},
+	[SCU1_CLK_GATE_I3C15CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "i3c15clk-gate",
+		.parent_names = (const char *[]){ "soc1-ahb", },
+		.reg = SCU1_CLK_STOP,
+		.clk_idx = 31,
+	},
+	[SCU1_CLK_UART5] = {
+		.type = CLK_MUX,
+		.name = "uart5clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 5,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART5CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart5clk-gate",
+		.parent_names = (const char *[]){ "uart5clk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 0,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_UART6] = {
+		.type = CLK_MUX,
+		.name = "uart6clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 6,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART6CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart6clk-gate",
+		.parent_names = (const char *[]){ "uart6clk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 1,
+	},
+	[SCU1_CLK_UART7] = {
+		.type = CLK_MUX,
+		.name = "uart7clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 7,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART7CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart7clk-gate",
+		.parent_names = (const char *[]){ "uart7clk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 2,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_UART8] = {
+		.type = CLK_MUX,
+		.name = "uart8clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 8,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART8CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart8clk-gate",
+		.parent_names = (const char *[]){ "uart8clk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 3,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_UART9] = {
+		.type = CLK_MUX,
+		.name = "uart9clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 9,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART9CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart9clk-gate",
+		.parent_names = (const char *[]){ "uart9clk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 4,
+	},
+	[SCU1_CLK_UART10] = {
+		.type = CLK_MUX,
+		.name = "uart10clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 10,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART10CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart10clk-gate",
+		.parent_names = (const char *[]){ "uart10clk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 5,
+	},
+	[SCU1_CLK_UART11] = {
+		.type = CLK_MUX,
+		.name = "uart11clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 11,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART11CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart11clk-gate",
+		.parent_names = (const char *[]){ "uart11clk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 6,
+	},
+	[SCU1_CLK_UART12] = {
+		.type = CLK_MUX,
+		.name = "uart12clk",
+		.parent_names = (const char *[]){"uartxclk", "huartxclk", },
+		.num_parents = 2,
+		.reg = SCU1_CLK_SEL1,
+		.bit_shift = 12,
+		.bit_width = 1,
+	},
+	[SCU1_CLK_GATE_UART12CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "uart12clk-gate",
+		.parent_names = (const char *[]){ "uart12clk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 7,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_UART13] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "uart13clk",
+		.parent_names = (const char *[]){ "huartxclk", },
+		.mult = 1,
+		.div = 1,
+	},
+	[SCU1_CLK_UART14] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "uart14clk",
+		.parent_names = (const char *[]){ "huartxclk", },
+		.mult = 1,
+		.div = 1,
+	},
+	[SCU1_CLK_GATE_FSICLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "fsiclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 8,
+	},
+	[SCU1_CLK_GATE_LTPIPHYCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "ltpiphyclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 9,
+	},
+	[SCU1_CLK_GATE_LTPICLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "ltpiclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 10,
+	},
+	[SCU1_CLK_GATE_VGALCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "vgalclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 11,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_UHCICLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "usbuartclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 12,
+	},
+	[SCU1_CLK_CAN] = {
+		.type = CLK_FIXED_FACTOR,
+		.name = "canclk",
+		.parent_names = (const char *[]){ "soc1-apll", },
+		.mult = 1,
+		.div = 10,
+	},
+	[SCU1_CLK_GATE_CANCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "canclk-gate",
+		.parent_names = (const char *[]){ "canclk", },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 13,
+	},
+	[SCU1_CLK_GATE_PCICLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "pciclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 14,
+	},
+	[SCU1_CLK_GATE_SLICLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "soc1-sliclk-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 15,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_E2MCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "soc1-e2m-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 16,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_PORTCUSB2CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "portcusb2-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 17,
+		.flags = CLK_IS_CRITICAL,
+	},
+	[SCU1_CLK_GATE_PORTDUSB2CLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "portdusb2-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 18,
+	},
+	[SCU1_CLK_GATE_LTPI1TXCLK] = {
+		.type = CLK_GATE_ASPEED,
+		.name = "ltp1tx-gate",
+		.parent_names = (const char *[]){  },
+		.reg = SCU1_CLK_STOP2,
+		.clk_idx = 19,
+	},
+};
+
+static struct clk_hw *ast2700_clk_hw_register_pll(int clk_idx, void __iomem *reg,
+						  const struct ast2700_clk_info *clk,
+						  struct ast2700_clk_ctrl *clk_ctrl)
+{
+	int scu = clk_ctrl->clk_data->scu;
+	unsigned int mult, div;
+	u32 val;
+
+	if (!scu && clk_idx == SCU0_CLK_HPLL) {
+		val = readl(clk_ctrl->base + SCU0_HWSTRAP1);
+		if ((val & GENMASK(3, 2)) != 0) {
+			switch ((val & GENMASK(3, 2)) >> 2) {
+			case 1:
+				return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
+								       NULL, 0, 1900000000);
+			case 2:
+				return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
+								       NULL, 0, 1800000000);
+			case 3:
+				return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
+								       NULL, 0, 1700000000);
+			default:
+				return ERR_PTR(-EINVAL);
+			}
+		}
+	}
+
+	val = readl(reg);
+
+	if (val & BIT(24)) {
+		/* Pass through mode */
+		mult = 1;
+		div = 1;
+	} else {
+		u32 m = val & 0x1fff;
+		u32 n = (val >> 13) & 0x3f;
+		u32 p = (val >> 19) & 0xf;
+
+		if (scu) {
+			mult = (m + 1) / (n + 1);
+			div = (p + 1);
+		} else {
+			if (clk_idx == SCU0_CLK_MPLL) {
+				mult = m / (n + 1);
+				div = (p + 1);
+			} else {
+				mult = (m + 1) / (2 * (n + 1));
+				div = (p + 1);
+			}
+		}
+	}
+
+	return devm_clk_hw_register_fixed_factor(clk_ctrl->dev, clk->name,
+						 clk->parent_names[0], 0, mult, div);
+}
+
+static struct clk_hw *ast2700_clk_hw_register_uartpll(int clk_idx, void __iomem *reg,
+						      const struct ast2700_clk_info *clk,
+						      struct ast2700_clk_ctrl *clk_ctrl)
+{
+	unsigned int mult, div;
+	u32 val = readl(reg);
+	u32 r = val & 0xff;
+	u32 n = (val >> 8) & 0x3ff;
+
+	mult = r;
+	div = n * 2;
+
+	return devm_clk_hw_register_fixed_factor(clk_ctrl->dev, clk->name,
+						 clk->parent_names[0], 0, mult, div);
+}
+
+static struct clk_hw *ast2700_clk_hw_register_misc(int clk_idx, void __iomem *reg,
+						   const struct ast2700_clk_info *clk,
+						   struct ast2700_clk_ctrl *clk_ctrl)
+{
+	u32 div = 0;
+
+	if (clk_idx == SCU0_CLK_MPHY)
+		div = readl(reg) + 1;
+	else if (clk_idx == SCU0_CLK_U2PHY_REFCLK)
+		div = (GET_USB_REFCLK_DIV(readl(reg)) + 1) << 1;
+	else
+		return ERR_PTR(-EINVAL);
+
+	return devm_clk_hw_register_fixed_factor(clk_ctrl->dev, clk->name,
+						   clk->parent_names[0], clk->flags,
+						   1, div);
+}
+
+static int ast2700_clk_is_enabled(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	u32 clk = BIT(gate->bit_idx);
+	u32 reg;
+
+	reg = readl(gate->reg);
+
+	return !(reg & clk);
+}
+
+static int ast2700_clk_enable(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	u32 clk = BIT(gate->bit_idx);
+
+	if (readl(gate->reg) & clk)
+		writel(clk, gate->reg + 0x04);
+
+	return 0;
+}
+
+static void ast2700_clk_disable(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	u32 clk = BIT(gate->bit_idx);
+
+	/* Clock is set to enable, so use write to set register */
+	writel(clk, gate->reg);
+}
+
+static const struct clk_ops ast2700_clk_gate_ops = {
+	.enable = ast2700_clk_enable,
+	.disable = ast2700_clk_disable,
+	.is_enabled = ast2700_clk_is_enabled,
+};
+
+static struct clk_hw *ast2700_clk_hw_register_gate(struct device *dev, const char *name,
+						   const char *parent_name, unsigned long flags,
+						   void __iomem *reg, u8 clock_idx,
+						   u8 clk_gate_flags, spinlock_t *lock)
+{
+	struct clk_gate *gate;
+	struct clk_hw *hw;
+	struct clk_init_data init;
+	int ret = -EINVAL;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &ast2700_clk_gate_ops;
+	init.flags = flags;
+	init.parent_names = parent_name ? &parent_name : NULL;
+	init.num_parents = parent_name ? 1 : 0;
+
+	gate->reg = reg;
+	gate->bit_idx = clock_idx;
+	gate->flags = clk_gate_flags;
+	gate->lock = lock;
+	gate->hw.init = &init;
+
+	hw = &gate->hw;
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+
+	return hw;
+}
+
+static int ast2700_soc_clk_probe(struct platform_device *pdev)
+{
+	struct ast2700_clk_data *clk_data;
+	struct ast2700_clk_ctrl *clk_ctrl;
+	struct clk_hw_onecell_data *clk_hw_data;
+	struct device *dev = &pdev->dev;
+	void __iomem *clk_base;
+	struct clk_hw **hws;
+	char *reset_name;
+	int ret;
+	int i;
+
+	clk_ctrl = devm_kzalloc(dev, sizeof(*clk_ctrl), GFP_KERNEL);
+	if (!clk_ctrl)
+		return -ENOMEM;
+	clk_ctrl->dev = dev;
+	dev_set_drvdata(&pdev->dev, clk_ctrl);
+
+	spin_lock_init(&clk_ctrl->lock);
+
+	clk_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(clk_base))
+		return PTR_ERR(clk_base);
+
+	clk_ctrl->base = clk_base;
+
+	clk_data = (struct ast2700_clk_data *)of_device_get_match_data(dev);
+	if (!clk_data)
+		return devm_of_platform_populate(dev);
+
+	clk_ctrl->clk_data = clk_data;
+	reset_name = devm_kasprintf(dev, GFP_KERNEL, "reset%d", clk_data->scu);
+
+	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, clk_data->nr_clks),
+				   GFP_KERNEL);
+	if (!clk_hw_data)
+		return -ENOMEM;
+
+	clk_hw_data->num = clk_data->nr_clks;
+	hws = clk_hw_data->hws;
+
+	for (i = 0; i < clk_data->nr_clks; i++) {
+		const struct ast2700_clk_info *clk = &clk_data->clk_info[i];
+		void __iomem *reg = clk_ctrl->base + clk->reg;
+
+		if (clk->type == CLK_FIXED) {
+			hws[i] = devm_clk_hw_register_fixed_rate(dev, clk->name, NULL,
+								 clk->flags, clk->fixed_rate);
+		} else if (clk->type == CLK_FIXED_FACTOR) {
+			hws[i] = devm_clk_hw_register_fixed_factor(dev, clk->name,
+								   clk->parent_names[0], clk->flags,
+								   clk->mult, clk->div);
+		} else if (clk->type == CLK_PLL) {
+			hws[i] = ast2700_clk_hw_register_pll(i, reg, clk, clk_ctrl);
+		} else if (clk->type == CLK_UART_PLL) {
+			hws[i] = ast2700_clk_hw_register_uartpll(i, reg, clk, clk_ctrl);
+		} else if (clk->type == CLK_MUX) {
+			hws[i] = devm_clk_hw_register_mux(dev, clk->name, clk->parent_names,
+							  clk->num_parents, clk->flags, reg,
+							  clk->bit_shift, clk->bit_width,
+							  0, &clk_ctrl->lock);
+		} else if (clk->type == CLK_MISC) {
+			hws[i] = ast2700_clk_hw_register_misc(i, reg, clk, clk_ctrl);
+		} else if (clk->type == CLK_DIVIDER) {
+			hws[i] = devm_clk_hw_register_divider(dev, clk->name, clk->parent_names[0],
+							      clk->flags, reg, clk->bit_shift,
+							      clk->bit_width, 0,
+							      &clk_ctrl->lock);
+		} else if (clk->type == CLK_DIV_TABLE) {
+			hws[i] = clk_hw_register_divider_table(dev, clk->name, clk->parent_names[0],
+							       clk->flags, reg, clk->bit_shift,
+							       clk->bit_width, 0,
+							       clk->div_table, &clk_ctrl->lock);
+		} else if (clk->type == CLK_GATE_ASPEED) {
+			hws[i] = ast2700_clk_hw_register_gate(dev, clk->name, clk->parent_names[0],
+							      clk->flags, reg, clk->clk_idx,
+							      clk->flags, &clk_ctrl->lock);
+		} else {
+			hws[i] = clk_hw_register_gate(dev, clk->name, clk->parent_names[0],
+						      clk->flags, reg, clk->clk_idx, clk->flags,
+						      &clk_ctrl->lock);
+		}
+
+		if (IS_ERR(hws[i]))
+			return PTR_ERR(hws[i]);
+	}
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data);
+	if (ret)
+		return ret;
+
+	return aspeed_reset_controller_register(dev, clk_base, reset_name);
+}
+
+static const struct ast2700_clk_data ast2700_clk0_data = {
+	.scu = 0,
+	.nr_clks = ARRAY_SIZE(ast2700_scu0_clk_info),
+	.clk_info = ast2700_scu0_clk_info,
+};
+
+static const struct ast2700_clk_data ast2700_clk1_data = {
+	.scu = 1,
+	.nr_clks = ARRAY_SIZE(ast2700_scu1_clk_info),
+	.clk_info = ast2700_scu1_clk_info,
+};
+
+static const struct of_device_id ast2700_scu_match[] = {
+	{ .compatible = "aspeed,ast2700-scu0", .data = &ast2700_clk0_data },
+	{ .compatible = "aspeed,ast2700-scu1", .data = &ast2700_clk1_data },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, ast2700_scu_match);
+
+static struct platform_driver ast2700_scu_driver = {
+	.driver = {
+		.name = "clk-ast2700",
+		.of_match_table = ast2700_scu_match,
+	},
+};
+
+builtin_platform_driver_probe(ast2700_scu_driver, ast2700_soc_clk_probe);
-- 
2.34.1



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

* Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-10-28  5:30 ` [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver Ryan Chen
@ 2024-10-30 21:01   ` Stephen Boyd
  2024-10-31  7:24     ` Ryan Chen
  2024-10-30 21:02   ` Stephen Boyd
  2024-10-31  0:44   ` kernel test robot
  2 siblings, 1 reply; 14+ messages in thread
From: Stephen Boyd @ 2024-10-30 21:01 UTC (permalink / raw)
  To: andrew, conor+dt, devicetree, dmitry.baryshkov, joel, krzk+dt,
	lee, linux-arm-kernel, linux-aspeed, linux-clk, linux-kernel,
	mturquette, p.zabel, robh, ryan_chen

Quoting Ryan Chen (2024-10-27 22:30:18)
> diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c
> new file mode 100644
> index 000000000000..db9ee5031b7c
> --- /dev/null
> +++ b/drivers/clk/clk-ast2700.c
> @@ -0,0 +1,1513 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024 ASPEED Technology Inc.
> + * Author: Ryan Chen <ryan_chen@aspeedtech.com>
> + */
> +
> +#include <linux/auxiliary_bus.h>

Is this include used?

> +#include <linux/clk-provider.h>
> +#include <linux/of_address.h>

Is this include used?

> +#include <linux/of_device.h>

Probably should be mod_devicetable.h here

> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/units.h>
> +
> +#include <dt-bindings/clock/aspeed,ast2700-scu.h>
> +#include <soc/aspeed/reset-aspeed.h>

This include can go before dt-bindings.

> +
> +#define SCU_CLK_12MHZ (12 * HZ_PER_MHZ)
> +#define SCU_CLK_24MHZ (24 * HZ_PER_MHZ)
> +#define SCU_CLK_25MHZ (25 * HZ_PER_MHZ)
> +#define SCU_CLK_192MHZ (192 * HZ_PER_MHZ)
> +
> +/* SOC0 */
> +#define SCU0_HWSTRAP1 0x010
> +#define SCU0_CLK_STOP 0x240
> +#define SCU0_CLK_SEL1 0x280
> +#define SCU0_CLK_SEL2 0x284
> +#define GET_USB_REFCLK_DIV(x) ((GENMASK(23, 20) & (x)) >> 20)
> +#define UART_DIV13_EN BIT(30)
> +#define SCU0_HPLL_PARAM 0x300
> +#define SCU0_DPLL_PARAM 0x308
> +#define SCU0_MPLL_PARAM 0x310
> +#define SCU0_D0CLK_PARAM 0x320
> +#define SCU0_D1CLK_PARAM 0x330
> +#define SCU0_CRT0CLK_PARAM 0x340
> +#define SCU0_CRT1CLK_PARAM 0x350
> +#define SCU0_MPHYCLK_PARAM 0x360

It would be easier to read if these things were tabbed out a little.

#define SCU0_MPHYCLK_PARAM			0x360

> +
> +/* SOC1 */
> +#define SCU1_REVISION_ID 0x0
> +#define REVISION_ID GENMASK(23, 16)
> +#define SCU1_CLK_STOP 0x240
> +#define SCU1_CLK_STOP2 0x260
> +#define SCU1_CLK_SEL1 0x280
> +#define SCU1_CLK_SEL2 0x284
> +#define UXCLK_MASK GENMASK(1, 0)
> +#define HUXCLK_MASK GENMASK(4, 3)
> +#define SCU1_HPLL_PARAM 0x300
> +#define SCU1_APLL_PARAM 0x310
> +#define SCU1_DPLL_PARAM 0x320
> +#define SCU1_UXCLK_CTRL 0x330
> +#define SCU1_HUXCLK_CTRL 0x334
> +#define SCU1_MAC12_CLK_DLY 0x390
> +#define SCU1_MAC12_CLK_DLY_100M 0x394
> +#define SCU1_MAC12_CLK_DLY_10M 0x398
> +
> +enum {
> +       CLK_MUX,
> +       CLK_PLL,
> +       CLK_GATE,
> +       CLK_MISC,
> +       CLK_FIXED,
> +       CLK_DIVIDER,
> +       CLK_UART_PLL,
> +       CLK_DIV_TABLE,
> +       CLK_FIXED_FACTOR,
> +       CLK_GATE_ASPEED,
> +};
> +
> +struct ast2700_clk_info {
> +       const char *name;
> +       const char * const *parent_names;

Please don't use strings for parent names.

> +       const struct clk_div_table *div_table;
> +       unsigned long fixed_rate;
> +       unsigned int mult;
> +       unsigned int div;
> +       u32 reg;
> +       u32 flags;
> +       u32 type;
> +       u8 clk_idx;
> +       u8 bit_shift;
> +       u8 bit_width;
> +       u8 num_parents;
> +};
> +
[...]
> +
> +static const struct clk_div_table ast2700_clk_div_table2[] = {
> +       { 0x0, 2 },
> +       { 0x1, 4 },
> +       { 0x2, 6 },
> +       { 0x3, 8 },
> +       { 0x4, 10 },
> +       { 0x5, 12 },
> +       { 0x6, 14 },
> +       { 0x7, 16 },

Isn't this the default divider setting for struct clk_divider?

> +       { 0 }
> +};
> +
> +static const struct clk_div_table ast2700_clk_uart_div_table[] = {
> +       { 0x0, 1 },
> +       { 0x1, 13 },
> +       { 0 }
[...]
> +               .bit_shift = 23,
> +               .bit_width = 3,
> +               .div_table = ast2700_clk_div_table2,
> +       },
> +       [SCU0_CLK_GATE_MCLK] = {
> +               .type = CLK_GATE_ASPEED,
> +               .name = "mclk-gate",
> +               .parent_names = (const char *[]){ "soc0-mpll", },
> +               .reg = SCU0_CLK_STOP,
> +               .clk_idx = 0,
> +               .flags = CLK_IS_CRITICAL,
> +       },
> +       [SCU0_CLK_GATE_ECLK] = {
> +               .type = CLK_GATE_ASPEED,
> +               .name = "eclk-gate",
> +               .parent_names = (const char *[]){  },
> +               .reg = SCU0_CLK_STOP,
> +               .clk_idx = 1,
> +       },
> +       [SCU0_CLK_GATE_2DCLK] = {
> +               .type = CLK_GATE_ASPEED,
> +               .name = "gclk-gate",
> +               .parent_names = (const char *[]){  },

This has no parent? Why is parent_names set to an empty array?

> +               .reg = SCU0_CLK_STOP,
> +               .clk_idx = 2,
> +       },
> +       [SCU0_CLK_GATE_VCLK] = {
[...]
> +
> +static struct clk_hw *ast2700_clk_hw_register_pll(int clk_idx, void __iomem *reg,
> +                                                 const struct ast2700_clk_info *clk,
> +                                                 struct ast2700_clk_ctrl *clk_ctrl)
> +{
> +       int scu = clk_ctrl->clk_data->scu;
> +       unsigned int mult, div;
> +       u32 val;
> +
> +       if (!scu && clk_idx == SCU0_CLK_HPLL) {
> +               val = readl(clk_ctrl->base + SCU0_HWSTRAP1);
> +               if ((val & GENMASK(3, 2)) != 0) {
> +                       switch ((val & GENMASK(3, 2)) >> 2) {
> +                       case 1:
> +                               return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
> +                                                                      NULL, 0, 1900000000);
> +                       case 2:
> +                               return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
> +                                                                      NULL, 0, 1800000000);
> +                       case 3:
> +                               return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
> +                                                                      NULL, 0, 1700000000);
> +                       default:
> +                               return ERR_PTR(-EINVAL);
> +                       }
> +               }

What if it is 0? Were we supposed to return an error? Why isn't HPLL a
different type of PLL so that this function can be broken up into two
PLL registration functions?

> +       }
> +
> +       val = readl(reg);
> +
> +       if (val & BIT(24)) {
> +               /* Pass through mode */
> +               mult = 1;
> +               div = 1;
> +       } else {
> +               u32 m = val & 0x1fff;
> +               u32 n = (val >> 13) & 0x3f;
> +               u32 p = (val >> 19) & 0xf;
> +
> +               if (scu) {
> +                       mult = (m + 1) / (n + 1);
> +                       div = (p + 1);
> +               } else {
> +                       if (clk_idx == SCU0_CLK_MPLL) {
> +                               mult = m / (n + 1);
> +                               div = (p + 1);
> +                       } else {
> +                               mult = (m + 1) / (2 * (n + 1));
> +                               div = (p + 1);
> +                       }
> +               }
> +       }
> +
> +       return devm_clk_hw_register_fixed_factor(clk_ctrl->dev, clk->name,
> +                                                clk->parent_names[0], 0, mult, div);
> +}
> +
[...]
> +
> +static int ast2700_soc_clk_probe(struct platform_device *pdev)
> +{
> +       struct ast2700_clk_data *clk_data;
> +       struct ast2700_clk_ctrl *clk_ctrl;
> +       struct clk_hw_onecell_data *clk_hw_data;
> +       struct device *dev = &pdev->dev;
> +       void __iomem *clk_base;
> +       struct clk_hw **hws;
> +       char *reset_name;
> +       int ret;
> +       int i;
> +
> +       clk_ctrl = devm_kzalloc(dev, sizeof(*clk_ctrl), GFP_KERNEL);
> +       if (!clk_ctrl)
> +               return -ENOMEM;
> +       clk_ctrl->dev = dev;
> +       dev_set_drvdata(&pdev->dev, clk_ctrl);
> +
> +       spin_lock_init(&clk_ctrl->lock);
> +
> +       clk_base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(clk_base))
> +               return PTR_ERR(clk_base);
> +
> +       clk_ctrl->base = clk_base;
> +
> +       clk_data = (struct ast2700_clk_data *)of_device_get_match_data(dev);

Just
	clk_data = device_get_match_data(dev);

> +       if (!clk_data)
> +               return devm_of_platform_populate(dev);

What is being populated? Isn't there always clk_data?

> +
> +       clk_ctrl->clk_data = clk_data;
> +       reset_name = devm_kasprintf(dev, GFP_KERNEL, "reset%d", clk_data->scu);
> +
> +       clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, clk_data->nr_clks),
> +                                  GFP_KERNEL);
> +       if (!clk_hw_data)
> +               return -ENOMEM;
> +
> +       clk_hw_data->num = clk_data->nr_clks;
> +       hws = clk_hw_data->hws;
> +
> +       for (i = 0; i < clk_data->nr_clks; i++) {
> +               const struct ast2700_clk_info *clk = &clk_data->clk_info[i];
> +               void __iomem *reg = clk_ctrl->base + clk->reg;
> +
> +               if (clk->type == CLK_FIXED) {
> +                       hws[i] = devm_clk_hw_register_fixed_rate(dev, clk->name, NULL,
> +                                                                clk->flags, clk->fixed_rate);
> +               } else if (clk->type == CLK_FIXED_FACTOR) {
> +                       hws[i] = devm_clk_hw_register_fixed_factor(dev, clk->name,
> +                                                                  clk->parent_names[0], clk->flags,
> +                                                                  clk->mult, clk->div);
> +               } else if (clk->type == CLK_PLL) {
> +                       hws[i] = ast2700_clk_hw_register_pll(i, reg, clk, clk_ctrl);
> +               } else if (clk->type == CLK_UART_PLL) {
> +                       hws[i] = ast2700_clk_hw_register_uartpll(i, reg, clk, clk_ctrl);
> +               } else if (clk->type == CLK_MUX) {
> +                       hws[i] = devm_clk_hw_register_mux(dev, clk->name, clk->parent_names,

Please don't use strings for parent_names. Use clk_hw pointers or DT
indices.

> +                                                         clk->num_parents, clk->flags, reg,
> +                                                         clk->bit_shift, clk->bit_width,
> +                                                         0, &clk_ctrl->lock);
> +               } else if (clk->type == CLK_MISC) {
> +                       hws[i] = ast2700_clk_hw_register_misc(i, reg, clk, clk_ctrl);
> +               } else if (clk->type == CLK_DIVIDER) {
> +                       hws[i] = devm_clk_hw_register_divider(dev, clk->name, clk->parent_names[0],
> +                                                             clk->flags, reg, clk->bit_shift,
> +                                                             clk->bit_width, 0,
> +                                                             &clk_ctrl->lock);
> +               } else if (clk->type == CLK_DIV_TABLE) {
> +                       hws[i] = clk_hw_register_divider_table(dev, clk->name, clk->parent_names[0],
> +                                                              clk->flags, reg, clk->bit_shift,
> +                                                              clk->bit_width, 0,
> +                                                              clk->div_table, &clk_ctrl->lock);
> +               } else if (clk->type == CLK_GATE_ASPEED) {
> +                       hws[i] = ast2700_clk_hw_register_gate(dev, clk->name, clk->parent_names[0],
> +                                                             clk->flags, reg, clk->clk_idx,
> +                                                             clk->flags, &clk_ctrl->lock);
> +               } else {
> +                       hws[i] = clk_hw_register_gate(dev, clk->name, clk->parent_names[0],
> +                                                     clk->flags, reg, clk->clk_idx, clk->flags,
> +                                                     &clk_ctrl->lock);
> +               }
> +
> +               if (IS_ERR(hws[i]))
> +                       return PTR_ERR(hws[i]);
> +       }
> +
> +       ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data);
> +       if (ret)
> +               return ret;
> +
> +       return aspeed_reset_controller_register(dev, clk_base, reset_name);
> +}
> +
> +static const struct ast2700_clk_data ast2700_clk0_data = {
> +       .scu = 0,
> +       .nr_clks = ARRAY_SIZE(ast2700_scu0_clk_info),
> +       .clk_info = ast2700_scu0_clk_info,
> +};
> +
> +static const struct ast2700_clk_data ast2700_clk1_data = {
> +       .scu = 1,
> +       .nr_clks = ARRAY_SIZE(ast2700_scu1_clk_info),
> +       .clk_info = ast2700_scu1_clk_info,
> +};
> +
> +static const struct of_device_id ast2700_scu_match[] = {
> +       { .compatible = "aspeed,ast2700-scu0", .data = &ast2700_clk0_data },
> +       { .compatible = "aspeed,ast2700-scu1", .data = &ast2700_clk1_data },
> +       { /* sentinel */ }
> +};
> +
> +MODULE_DEVICE_TABLE(of, ast2700_scu_match);
> +
> +static struct platform_driver ast2700_scu_driver = {
> +       .driver = {
> +               .name = "clk-ast2700",
> +               .of_match_table = ast2700_scu_match,
> +       },
> +};
> +
> +builtin_platform_driver_probe(ast2700_scu_driver, ast2700_soc_clk_probe);

Use module_platform_driver_probe() and make the config tristate. I don't
see what's preventing this from being a module.


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

* Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-10-28  5:30 ` [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver Ryan Chen
  2024-10-30 21:01   ` Stephen Boyd
@ 2024-10-30 21:02   ` Stephen Boyd
  2024-10-31  0:44   ` kernel test robot
  2 siblings, 0 replies; 14+ messages in thread
From: Stephen Boyd @ 2024-10-30 21:02 UTC (permalink / raw)
  To: andrew, conor+dt, devicetree, dmitry.baryshkov, joel, krzk+dt,
	lee, linux-arm-kernel, linux-aspeed, linux-clk, linux-kernel,
	mturquette, p.zabel, robh, ryan_chen

One more thing. Please remove the period from the subject. No other
patch in this series has a period at the end.


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

* Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-10-28  5:30 ` [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver Ryan Chen
  2024-10-30 21:01   ` Stephen Boyd
  2024-10-30 21:02   ` Stephen Boyd
@ 2024-10-31  0:44   ` kernel test robot
  2 siblings, 0 replies; 14+ messages in thread
From: kernel test robot @ 2024-10-31  0:44 UTC (permalink / raw)
  To: Ryan Chen, lee, robh, krzk+dt, conor+dt, joel, andrew, mturquette,
	sboyd, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, linux-clk, dmitry.baryshkov
  Cc: oe-kbuild-all

Hi Ryan,

kernel test robot noticed the following build errors:

[auto build test ERROR on clk/clk-next]
[also build test ERROR on pza/reset/next lee-mfd/for-mfd-next lee-leds/for-leds-next linus/master lee-mfd/for-mfd-fixes v6.12-rc5 next-20241030]
[cannot apply to pza/imx-drm/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ryan-Chen/dt-bindings-mfd-aspeed-support-for-AST2700/20241028-133255
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
patch link:    https://lore.kernel.org/r/20241028053018.2579200-4-ryan_chen%40aspeedtech.com
patch subject: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
config: csky-randconfig-001-20241031 (https://download.01.org/0day-ci/archive/20241031/202410310827.OOitgPg0-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241031/202410310827.OOitgPg0-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202410310827.OOitgPg0-lkp@intel.com/

All errors (new ones prefixed by >>):

   csky-linux-ld: drivers/clk/clk-ast2700.o: in function `ast2700_soc_clk_probe':
   clk-ast2700.c:(.text+0x530): undefined reference to `aspeed_reset_controller_register'
>> csky-linux-ld: clk-ast2700.c:(.text+0x558): undefined reference to `aspeed_reset_controller_register'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


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

* RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-10-30 21:01   ` Stephen Boyd
@ 2024-10-31  7:24     ` Ryan Chen
  2024-11-21 23:06       ` Stephen Boyd
  0 siblings, 1 reply; 14+ messages in thread
From: Ryan Chen @ 2024-10-31  7:24 UTC (permalink / raw)
  To: Stephen Boyd, andrew@codeconstruct.com.au, conor+dt@kernel.org,
	devicetree@vger.kernel.org, dmitry.baryshkov@linaro.org,
	joel@jms.id.au, krzk+dt@kernel.org, lee@kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org, linux-clk@vger.kernel.org,
	linux-kernel@vger.kernel.org, mturquette@baylibre.com,
	p.zabel@pengutronix.de, robh@kernel.org

> Subject: Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> 
> Quoting Ryan Chen (2024-10-27 22:30:18)
> > diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c new
> > file mode 100644 index 000000000000..db9ee5031b7c
> > --- /dev/null
> > +++ b/drivers/clk/clk-ast2700.c
> > @@ -0,0 +1,1513 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2024 ASPEED Technology Inc.
> > + * Author: Ryan Chen <ryan_chen@aspeedtech.com>  */
> > +
> > +#include <linux/auxiliary_bus.h>
> 
> Is this include used?

Will remove it.

> 
> > +#include <linux/clk-provider.h>
> > +#include <linux/of_address.h>
> 
> Is this include used?

Will remove, and add #include <linux/io.h> fore readl/writel
> 
> > +#include <linux/of_device.h>
> 
> Probably should be mod_devicetable.h here

Yes, will add #include <linux/mod_devicetable.h>
> 
> > +#include <linux/of_platform.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/slab.h>
> > +#include <linux/units.h>
> > +
> > +#include <dt-bindings/clock/aspeed,ast2700-scu.h>
> > +#include <soc/aspeed/reset-aspeed.h>
> 
> This include can go before dt-bindings.

Will update following.
#include <soc/aspeed/reset-aspeed.h>
#include <dt-bindings/clock/aspeed,ast2700-scu.h>
> 
> > +
> > +#define SCU_CLK_12MHZ (12 * HZ_PER_MHZ) #define SCU_CLK_24MHZ
> (24 *
> > +HZ_PER_MHZ) #define SCU_CLK_25MHZ (25 * HZ_PER_MHZ) #define
> > +SCU_CLK_192MHZ (192 * HZ_PER_MHZ)
> > +
> > +/* SOC0 */
> > +#define SCU0_HWSTRAP1 0x010
> > +#define SCU0_CLK_STOP 0x240
> > +#define SCU0_CLK_SEL1 0x280
> > +#define SCU0_CLK_SEL2 0x284
> > +#define GET_USB_REFCLK_DIV(x) ((GENMASK(23, 20) & (x)) >> 20) #define
> > +UART_DIV13_EN BIT(30) #define SCU0_HPLL_PARAM 0x300 #define
> > +SCU0_DPLL_PARAM 0x308 #define SCU0_MPLL_PARAM 0x310 #define
> > +SCU0_D0CLK_PARAM 0x320 #define SCU0_D1CLK_PARAM 0x330 #define
> > +SCU0_CRT0CLK_PARAM 0x340 #define SCU0_CRT1CLK_PARAM 0x350
> #define
> > +SCU0_MPHYCLK_PARAM 0x360
> 
> It would be easier to read if these things were tabbed out a little.
> 
> #define SCU0_MPHYCLK_PARAM			0x360

Thank, all those will update by tabbed.
> 
> > +
> > +/* SOC1 */
> > +#define SCU1_REVISION_ID 0x0
> > +#define REVISION_ID GENMASK(23, 16)
> > +#define SCU1_CLK_STOP 0x240
> > +#define SCU1_CLK_STOP2 0x260
> > +#define SCU1_CLK_SEL1 0x280
> > +#define SCU1_CLK_SEL2 0x284
> > +#define UXCLK_MASK GENMASK(1, 0)
> > +#define HUXCLK_MASK GENMASK(4, 3)
> > +#define SCU1_HPLL_PARAM 0x300
> > +#define SCU1_APLL_PARAM 0x310
> > +#define SCU1_DPLL_PARAM 0x320
> > +#define SCU1_UXCLK_CTRL 0x330
> > +#define SCU1_HUXCLK_CTRL 0x334
> > +#define SCU1_MAC12_CLK_DLY 0x390
> > +#define SCU1_MAC12_CLK_DLY_100M 0x394 #define
> SCU1_MAC12_CLK_DLY_10M
> > +0x398
> > +
> > +enum {
> > +       CLK_MUX,
> > +       CLK_PLL,
> > +       CLK_GATE,
> > +       CLK_MISC,
> > +       CLK_FIXED,
> > +       CLK_DIVIDER,
> > +       CLK_UART_PLL,
> > +       CLK_DIV_TABLE,
> > +       CLK_FIXED_FACTOR,
> > +       CLK_GATE_ASPEED,
> > +};
> > +
> > +struct ast2700_clk_info {
> > +       const char *name;
> > +       const char * const *parent_names;
> 
> Please don't use strings for parent names.
Sorry, do you mean use clk_parent_data struct for parent?
	+const struct clk_parent_data	parent;		/* For gate */
	+const struct clk_parent_data	*parents;		/* For mux */

> 
> > +       const struct clk_div_table *div_table;
> > +       unsigned long fixed_rate;
> > +       unsigned int mult;
> > +       unsigned int div;
> > +       u32 reg;
> > +       u32 flags;
> > +       u32 type;
> > +       u8 clk_idx;
> > +       u8 bit_shift;
> > +       u8 bit_width;
> > +       u8 num_parents;
> > +};
> > +
> [...]
> > +
> > +static const struct clk_div_table ast2700_clk_div_table2[] = {
> > +       { 0x0, 2 },
> > +       { 0x1, 4 },
> > +       { 0x2, 6 },
> > +       { 0x3, 8 },
> > +       { 0x4, 10 },
> > +       { 0x5, 12 },
> > +       { 0x6, 14 },
> > +       { 0x7, 16 },
> 
> Isn't this the default divider setting for struct clk_divider?
Sorry, I don't catch your point.
the SoC do have default divider setting. But it can be modified.
And also have different divider table setting.
> 
> > +       { 0 }
> > +};
> > +
> > +static const struct clk_div_table ast2700_clk_uart_div_table[] = {
> > +       { 0x0, 1 },
> > +       { 0x1, 13 },
> > +       { 0 }
> [...]
> > +               .bit_shift = 23,
> > +               .bit_width = 3,
> > +               .div_table = ast2700_clk_div_table2,
> > +       },
> > +       [SCU0_CLK_GATE_MCLK] = {
> > +               .type = CLK_GATE_ASPEED,
> > +               .name = "mclk-gate",
> > +               .parent_names = (const char *[]){ "soc0-mpll", },
> > +               .reg = SCU0_CLK_STOP,
> > +               .clk_idx = 0,
> > +               .flags = CLK_IS_CRITICAL,
> > +       },
> > +       [SCU0_CLK_GATE_ECLK] = {
> > +               .type = CLK_GATE_ASPEED,
> > +               .name = "eclk-gate",
> > +               .parent_names = (const char *[]){  },
> > +               .reg = SCU0_CLK_STOP,
> > +               .clk_idx = 1,
> > +       },
> > +       [SCU0_CLK_GATE_2DCLK] = {
> > +               .type = CLK_GATE_ASPEED,
> > +               .name = "gclk-gate",
> > +               .parent_names = (const char *[]){  },
> 
> This has no parent? Why is parent_names set to an empty array?
Due to I use clk->parent_names[0] for clk_hw_register_gate, const char *name parameter input.
If null, that will cause panic for NULL point.

> 
> > +               .reg = SCU0_CLK_STOP,
> > +               .clk_idx = 2,
> > +       },
> > +       [SCU0_CLK_GATE_VCLK] = {
> [...]
> > +
> > +static struct clk_hw *ast2700_clk_hw_register_pll(int clk_idx, void
> __iomem *reg,
> > +                                                 const struct
> ast2700_clk_info *clk,
> > +                                                 struct
> > +ast2700_clk_ctrl *clk_ctrl) {
> > +       int scu = clk_ctrl->clk_data->scu;
> > +       unsigned int mult, div;
> > +       u32 val;
> > +
> > +       if (!scu && clk_idx == SCU0_CLK_HPLL) {
> > +               val = readl(clk_ctrl->base + SCU0_HWSTRAP1);
> > +               if ((val & GENMASK(3, 2)) != 0) {
> > +                       switch ((val & GENMASK(3, 2)) >> 2) {
> > +                       case 1:
> > +                               return
> devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
> > +
> NULL, 0, 1900000000);
> > +                       case 2:
> > +                               return
> devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
> > +
> NULL, 0, 1800000000);
> > +                       case 3:
> > +                               return
> devm_clk_hw_register_fixed_rate(clk_ctrl->dev, "soc0-hpll",
> > +
> NULL, 0, 1700000000);
> > +                       default:
> > +                               return ERR_PTR(-EINVAL);
> > +                       }
> > +               }
> 
> What if it is 0? Were we supposed to return an error? Why isn't HPLL a
> different type of PLL so that this function can be broken up into two PLL
> registration functions?

Sorry, I miss 0: It will be another fix clk. It need add.
And also I will separate another PLL registration function, add new enum clk type : CLK_HPLL_SOC0
> 
> > +       }
> > +
> > +       val = readl(reg);
> > +
> > +       if (val & BIT(24)) {
> > +               /* Pass through mode */
> > +               mult = 1;
> > +               div = 1;
> > +       } else {
> > +               u32 m = val & 0x1fff;
> > +               u32 n = (val >> 13) & 0x3f;
> > +               u32 p = (val >> 19) & 0xf;
> > +
> > +               if (scu) {
> > +                       mult = (m + 1) / (n + 1);
> > +                       div = (p + 1);
> > +               } else {
> > +                       if (clk_idx == SCU0_CLK_MPLL) {
> > +                               mult = m / (n + 1);
> > +                               div = (p + 1);
> > +                       } else {
> > +                               mult = (m + 1) / (2 * (n + 1));
> > +                               div = (p + 1);
> > +                       }
> > +               }
> > +       }
> > +
> > +       return devm_clk_hw_register_fixed_factor(clk_ctrl->dev,
> clk->name,
> > +
> clk->parent_names[0],
> > +0, mult, div); }
> > +
> [...]
> > +
> > +static int ast2700_soc_clk_probe(struct platform_device *pdev) {
> > +       struct ast2700_clk_data *clk_data;
> > +       struct ast2700_clk_ctrl *clk_ctrl;
> > +       struct clk_hw_onecell_data *clk_hw_data;
> > +       struct device *dev = &pdev->dev;
> > +       void __iomem *clk_base;
> > +       struct clk_hw **hws;
> > +       char *reset_name;
> > +       int ret;
> > +       int i;
> > +
> > +       clk_ctrl = devm_kzalloc(dev, sizeof(*clk_ctrl), GFP_KERNEL);
> > +       if (!clk_ctrl)
> > +               return -ENOMEM;
> > +       clk_ctrl->dev = dev;
> > +       dev_set_drvdata(&pdev->dev, clk_ctrl);
> > +
> > +       spin_lock_init(&clk_ctrl->lock);
> > +
> > +       clk_base = devm_platform_ioremap_resource(pdev, 0);
> > +       if (IS_ERR(clk_base))
> > +               return PTR_ERR(clk_base);
> > +
> > +       clk_ctrl->base = clk_base;
> > +
> > +       clk_data = (struct ast2700_clk_data
> > + *)of_device_get_match_data(dev);
> 
> Just
> 	clk_data = device_get_match_data(dev);
Will update.
> 
> > +       if (!clk_data)
> > +               return devm_of_platform_populate(dev);
> 
> What is being populated? Isn't there always clk_data?
Yes, it is always clk_data, I will modify to be following, is it ok?
If(!clk_data)
	Return -ENODEV;


> 
> > +
> > +       clk_ctrl->clk_data = clk_data;
> > +       reset_name = devm_kasprintf(dev, GFP_KERNEL, "reset%d",
> > + clk_data->scu);
> > +
> > +       clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
> clk_data->nr_clks),
> > +                                  GFP_KERNEL);
> > +       if (!clk_hw_data)
> > +               return -ENOMEM;
> > +
> > +       clk_hw_data->num = clk_data->nr_clks;
> > +       hws = clk_hw_data->hws;
> > +
> > +       for (i = 0; i < clk_data->nr_clks; i++) {
> > +               const struct ast2700_clk_info *clk =
> &clk_data->clk_info[i];
> > +               void __iomem *reg = clk_ctrl->base + clk->reg;
> > +
> > +               if (clk->type == CLK_FIXED) {
> > +                       hws[i] = devm_clk_hw_register_fixed_rate(dev,
> clk->name, NULL,
> > +
> clk->flags, clk->fixed_rate);
> > +               } else if (clk->type == CLK_FIXED_FACTOR) {
> > +                       hws[i] =
> devm_clk_hw_register_fixed_factor(dev, clk->name,
> > +
> clk->parent_names[0], clk->flags,
> > +
> clk->mult, clk->div);
> > +               } else if (clk->type == CLK_PLL) {
> > +                       hws[i] = ast2700_clk_hw_register_pll(i, reg,
> clk, clk_ctrl);
> > +               } else if (clk->type == CLK_UART_PLL) {
> > +                       hws[i] = ast2700_clk_hw_register_uartpll(i,
> reg, clk, clk_ctrl);
> > +               } else if (clk->type == CLK_MUX) {
> > +                       hws[i] = devm_clk_hw_register_mux(dev,
> > + clk->name, clk->parent_names,
> 
> Please don't use strings for parent_names. Use clk_hw pointers or DT indices.
Use clk_pareent_data is it ok ?

	+const struct clk_parent_data	parent;		/* For gate */
	+const struct clk_parent_data	*parents;		/* For mux */
> 
> > +
> clk->num_parents, clk->flags, reg,
> > +
> clk->bit_shift, clk->bit_width,
> > +                                                         0,
> &clk_ctrl->lock);
> > +               } else if (clk->type == CLK_MISC) {
> > +                       hws[i] = ast2700_clk_hw_register_misc(i, reg,
> clk, clk_ctrl);
> > +               } else if (clk->type == CLK_DIVIDER) {
> > +                       hws[i] = devm_clk_hw_register_divider(dev,
> clk->name, clk->parent_names[0],
> > +
> clk->flags, reg, clk->bit_shift,
> > +
> clk->bit_width, 0,
> > +
> &clk_ctrl->lock);
> > +               } else if (clk->type == CLK_DIV_TABLE) {
> > +                       hws[i] = clk_hw_register_divider_table(dev,
> clk->name, clk->parent_names[0],
> > +
> clk->flags, reg, clk->bit_shift,
> > +
> clk->bit_width, 0,
> > +
> clk->div_table, &clk_ctrl->lock);
> > +               } else if (clk->type == CLK_GATE_ASPEED) {
> > +                       hws[i] = ast2700_clk_hw_register_gate(dev,
> clk->name, clk->parent_names[0],
> > +
> clk->flags, reg, clk->clk_idx,
> > +
> clk->flags, &clk_ctrl->lock);
> > +               } else {
> > +                       hws[i] = clk_hw_register_gate(dev, clk->name,
> clk->parent_names[0],
> > +
> clk->flags, reg, clk->clk_idx, clk->flags,
> > +
> &clk_ctrl->lock);
> > +               }
> > +
> > +               if (IS_ERR(hws[i]))
> > +                       return PTR_ERR(hws[i]);
> > +       }
> > +
> > +       ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
> clk_hw_data);
> > +       if (ret)
> > +               return ret;
> > +
> > +       return aspeed_reset_controller_register(dev, clk_base,
> > +reset_name); }
> > +
> > +static const struct ast2700_clk_data ast2700_clk0_data = {
> > +       .scu = 0,
> > +       .nr_clks = ARRAY_SIZE(ast2700_scu0_clk_info),
> > +       .clk_info = ast2700_scu0_clk_info, };
> > +
> > +static const struct ast2700_clk_data ast2700_clk1_data = {
> > +       .scu = 1,
> > +       .nr_clks = ARRAY_SIZE(ast2700_scu1_clk_info),
> > +       .clk_info = ast2700_scu1_clk_info, };
> > +
> > +static const struct of_device_id ast2700_scu_match[] = {
> > +       { .compatible = "aspeed,ast2700-scu0", .data =
> &ast2700_clk0_data },
> > +       { .compatible = "aspeed,ast2700-scu1", .data =
> &ast2700_clk1_data },
> > +       { /* sentinel */ }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, ast2700_scu_match);
> > +
> > +static struct platform_driver ast2700_scu_driver = {
> > +       .driver = {
> > +               .name = "clk-ast2700",
> > +               .of_match_table = ast2700_scu_match,
> > +       },
> > +};
> > +
> > +builtin_platform_driver_probe(ast2700_scu_driver,
> > +ast2700_soc_clk_probe);
> 
> Use module_platform_driver_probe() and make the config tristate. I don't see
> what's preventing this from being a module.
Will update. 

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

* RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-10-31  7:24     ` Ryan Chen
@ 2024-11-21 23:06       ` Stephen Boyd
  2024-12-02  3:12         ` Ryan Chen
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Boyd @ 2024-11-21 23:06 UTC (permalink / raw)
  To: Ryan Chen, andrew, conor+dt, devicetree, dmitry.baryshkov, joel,
	krzk+dt, lee, linux-arm-kernel, linux-aspeed, linux-clk,
	linux-kernel, mturquette, p.zabel, robh

Quoting Ryan Chen (2024-10-31 00:24:39)
> > Subject: Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> > 
> > Quoting Ryan Chen (2024-10-27 22:30:18)
> > > diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c new
> > > file mode 100644 index 000000000000..db9ee5031b7c
> > > --- /dev/null
> > > +++ b/drivers/clk/clk-ast2700.c
> > > @@ -0,0 +1,1513 @@
> > > +// SPDX-License-Identifier: GPL-2.0
[...]
> > > +struct ast2700_clk_info {
> > > +       const char *name;
> > > +       const char * const *parent_names;
> > 
> > Please don't use strings for parent names.
> Sorry, do you mean use clk_parent_data struct for parent?
>         +const struct clk_parent_data   parent;         /* For gate */
>         +const struct clk_parent_data   *parents;               /* For mux */

Yes.

> 
> > 
> > > +       const struct clk_div_table *div_table;
> > > +       unsigned long fixed_rate;
> > > +       unsigned int mult;
> > > +       unsigned int div;
> > > +       u32 reg;
> > > +       u32 flags;
> > > +       u32 type;
> > > +       u8 clk_idx;
> > > +       u8 bit_shift;
> > > +       u8 bit_width;
> > > +       u8 num_parents;
> > > +};
> > > +
> > [...]
> > > +
> > > +static const struct clk_div_table ast2700_clk_div_table2[] = {
> > > +       { 0x0, 2 },
> > > +       { 0x1, 4 },
> > > +       { 0x2, 6 },
> > > +       { 0x3, 8 },
> > > +       { 0x4, 10 },
> > > +       { 0x5, 12 },
> > > +       { 0x6, 14 },
> > > +       { 0x7, 16 },
> > 
> > Isn't this the default divider setting for struct clk_divider?
> Sorry, I don't catch your point.
> the SoC do have default divider setting. But it can be modified.
> And also have different divider table setting.

I mean that this is the way that struct clk_divider works already. So
you don't need to make the clk_div_table array for what is supported in
code.

> > 
> > > +       { 0 }
> > > +};
> > > +
> > > +static const struct clk_div_table ast2700_clk_uart_div_table[] = {
> > > +       { 0x0, 1 },
> > > +       { 0x1, 13 },
> > > +       { 0 }
> > [...]
> > > +               .bit_shift = 23,
> > > +               .bit_width = 3,
> > > +               .div_table = ast2700_clk_div_table2,
> > > +       },
> > > +       [SCU0_CLK_GATE_MCLK] = {
> > > +               .type = CLK_GATE_ASPEED,
> > > +               .name = "mclk-gate",
> > > +               .parent_names = (const char *[]){ "soc0-mpll", },
> > > +               .reg = SCU0_CLK_STOP,
> > > +               .clk_idx = 0,
> > > +               .flags = CLK_IS_CRITICAL,
> > > +       },
> > > +       [SCU0_CLK_GATE_ECLK] = {
> > > +               .type = CLK_GATE_ASPEED,
> > > +               .name = "eclk-gate",
> > > +               .parent_names = (const char *[]){  },
> > > +               .reg = SCU0_CLK_STOP,
> > > +               .clk_idx = 1,
> > > +       },
> > > +       [SCU0_CLK_GATE_2DCLK] = {
> > > +               .type = CLK_GATE_ASPEED,
> > > +               .name = "gclk-gate",
> > > +               .parent_names = (const char *[]){  },
> > 
> > This has no parent? Why is parent_names set to an empty array?
> Due to I use clk->parent_names[0] for clk_hw_register_gate, const char *name parameter input.
> If null, that will cause panic for NULL point.

But the parent is NULL? How many parents does this clk have?

> > 
> > > +       if (!clk_data)
> > > +               return devm_of_platform_populate(dev);
> > 
> > What is being populated? Isn't there always clk_data?
> Yes, it is always clk_data, I will modify to be following, is it ok?
> If(!clk_data)
>         Return -ENODEV;
> 

Sure.

> > 
> > Please don't use strings for parent_names. Use clk_hw pointers or DT indices.
> Use clk_pareent_data is it ok ?

Yes.


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

* RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-11-21 23:06       ` Stephen Boyd
@ 2024-12-02  3:12         ` Ryan Chen
  2024-12-04 23:24           ` Stephen Boyd
  0 siblings, 1 reply; 14+ messages in thread
From: Ryan Chen @ 2024-12-02  3:12 UTC (permalink / raw)
  To: Stephen Boyd, andrew@codeconstruct.com.au, conor+dt@kernel.org,
	devicetree@vger.kernel.org, dmitry.baryshkov@linaro.org,
	joel@jms.id.au, krzk+dt@kernel.org, lee@kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org, linux-clk@vger.kernel.org,
	linux-kernel@vger.kernel.org, mturquette@baylibre.com,
	p.zabel@pengutronix.de, robh@kernel.org

> > > Subject: Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> > >
> > > Quoting Ryan Chen (2024-10-27 22:30:18)
> > > > diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c
> > > > new file mode 100644 index 000000000000..db9ee5031b7c
> > > > --- /dev/null
> > > > +++ b/drivers/clk/clk-ast2700.c
> > > > @@ -0,0 +1,1513 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> [...]
> > > > +struct ast2700_clk_info {
> > > > +       const char *name;
> > > > +       const char * const *parent_names;
> > >
> > > Please don't use strings for parent names.
> > Sorry, do you mean use clk_parent_data struct for parent?
> >         +const struct clk_parent_data   parent;         /* For gate */
> >         +const struct clk_parent_data   *parents;               /*
> For mux */
> 
> Yes.
And I find a better way for parent_data. The following is my modification. 
And parent_data will be union data structure. Like following.
Is this good direction? 

#define DIVIDER_CLK(_id, _name, _parent, _reg, _shift, _width, _div_table) \
	[_id] = { \
		.type = CLK_DIVIDER, \
		.name = _name, \
		.data = { \
			.div = { \
				.parent = _parent, \
				.reg = _reg, \
				.bit_shift = _shift, \
				.bit_width = _width, \
				.div_table = _div_table, \
			}, \
		}, \
	}
struct ast2700_clk_info {
	const char *name;
	u8 clk_idx;
	u32 reg;
	u32 type;
	union {
		struct ast2700_clk_fixed_factor_data factor;
		struct ast2700_clk_fixed_rate_data rate;
		struct ast2700_clk_gate_data gate;
		struct ast2700_clk_div_data div;
		struct ast2700_clk_pll_data pll;
		struct ast2700_clk_mux_data mux;
	} data;
};

struct ast2700_clk_div_data {
	const struct clk_div_table *div_table;
	const struct clk_parent_data *parent;
	u8 bit_shift;
	u8 bit_width;
	u32 reg;
};

static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = {
...........................
	DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
		    SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
......................
> 
> >
> > >
> > > > +       const struct clk_div_table *div_table;
> > > > +       unsigned long fixed_rate;
> > > > +       unsigned int mult;
> > > > +       unsigned int div;
> > > > +       u32 reg;
> > > > +       u32 flags;
> > > > +       u32 type;
> > > > +       u8 clk_idx;
> > > > +       u8 bit_shift;
> > > > +       u8 bit_width;
> > > > +       u8 num_parents;
> > > > +};
> > > > +
> > > [...]
> > > > +
> > > > +static const struct clk_div_table ast2700_clk_div_table2[] = {
> > > > +       { 0x0, 2 },
> > > > +       { 0x1, 4 },
> > > > +       { 0x2, 6 },
> > > > +       { 0x3, 8 },
> > > > +       { 0x4, 10 },
> > > > +       { 0x5, 12 },
> > > > +       { 0x6, 14 },
> > > > +       { 0x7, 16 },
> > >
> > > Isn't this the default divider setting for struct clk_divider?
> > Sorry, I don't catch your point.
> > the SoC do have default divider setting. But it can be modified.
> > And also have different divider table setting.
> 
> I mean that this is the way that struct clk_divider works already. So you don't
> need to make the clk_div_table array for what is supported in code.

Sorry, I understand your point. But I trace the code didn't get any clue. "clk_divider work already".
finally function call will be __clk_hw_register_divider
https://github.com/torvalds/linux/blob/master/drivers/clk/clk-divider.c#L589
It still need table point need to address. Can you give me more direction or example?


> 
> > >
> > > > +       { 0 }
> > > > +};
> > > > +
> > > > +static const struct clk_div_table ast2700_clk_uart_div_table[] = {
> > > > +       { 0x0, 1 },
> > > > +       { 0x1, 13 },
> > > > +       { 0 }
> > > [...]
> > > > +               .bit_shift = 23,
> > > > +               .bit_width = 3,
> > > > +               .div_table = ast2700_clk_div_table2,
> > > > +       },
> > > > +       [SCU0_CLK_GATE_MCLK] = {
> > > > +               .type = CLK_GATE_ASPEED,
> > > > +               .name = "mclk-gate",
> > > > +               .parent_names = (const char *[]){ "soc0-mpll", },
> > > > +               .reg = SCU0_CLK_STOP,
> > > > +               .clk_idx = 0,
> > > > +               .flags = CLK_IS_CRITICAL,
> > > > +       },
> > > > +       [SCU0_CLK_GATE_ECLK] = {
> > > > +               .type = CLK_GATE_ASPEED,
> > > > +               .name = "eclk-gate",
> > > > +               .parent_names = (const char *[]){  },
> > > > +               .reg = SCU0_CLK_STOP,
> > > > +               .clk_idx = 1,
> > > > +       },
> > > > +       [SCU0_CLK_GATE_2DCLK] = {
> > > > +               .type = CLK_GATE_ASPEED,
> > > > +               .name = "gclk-gate",
> > > > +               .parent_names = (const char *[]){  },
> > >
> > > This has no parent? Why is parent_names set to an empty array?
> > Due to I use clk->parent_names[0] for clk_hw_register_gate, const char
> *name parameter input.
> > If null, that will cause panic for NULL point.
> 
> But the parent is NULL? How many parents does this clk have?

I will remove this in array.
I will do parent_names = parent ? &parent->name : NULL; to check null.
> 
> > >
> > > > +       if (!clk_data)
> > > > +               return devm_of_platform_populate(dev);
> > >
> > > What is being populated? Isn't there always clk_data?
> > Yes, it is always clk_data, I will modify to be following, is it ok?
> > If(!clk_data)
> >         Return -ENODEV;
> >
> 
> Sure.
> 
> > >
> > > Please don't use strings for parent_names. Use clk_hw pointers or DT
> indices.
> > Use clk_pareent_data is it ok ?
> 
> Yes.

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

* RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-12-02  3:12         ` Ryan Chen
@ 2024-12-04 23:24           ` Stephen Boyd
  2024-12-05  0:48             ` Ryan Chen
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Boyd @ 2024-12-04 23:24 UTC (permalink / raw)
  To: Ryan Chen, andrew, conor+dt, devicetree, dmitry.baryshkov, joel,
	krzk+dt, lee, linux-arm-kernel, linux-aspeed, linux-clk,
	linux-kernel, mturquette, p.zabel, robh

Quoting Ryan Chen (2024-12-01 19:12:01)
> > > > Subject: Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> > > >
> > > > Quoting Ryan Chen (2024-10-27 22:30:18)
> > > > > diff --git a/drivers/clk/clk-ast2700.c b/drivers/clk/clk-ast2700.c
> > > > > new file mode 100644 index 000000000000..db9ee5031b7c
> > > > > --- /dev/null
> > > > > +++ b/drivers/clk/clk-ast2700.c
> > > > > @@ -0,0 +1,1513 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0
> > [...]
> > > > > +struct ast2700_clk_info {
> > > > > +       const char *name;
> > > > > +       const char * const *parent_names;
> > > >
> > > > Please don't use strings for parent names.
> > > Sorry, do you mean use clk_parent_data struct for parent?
> > >         +const struct clk_parent_data   parent;         /* For gate */
> > >         +const struct clk_parent_data   *parents;               /*
> > For mux */
> > 
> > Yes.
> And I find a better way for parent_data. The following is my modification. 
> And parent_data will be union data structure. Like following.
> Is this good direction? 

Looks OK.

> 
> #define DIVIDER_CLK(_id, _name, _parent, _reg, _shift, _width, _div_table) \
>         [_id] = { \
>                 .type = CLK_DIVIDER, \
>                 .name = _name, \
>                 .data = { \
>                         .div = { \
>                                 .parent = _parent, \
>                                 .reg = _reg, \
>                                 .bit_shift = _shift, \
>                                 .bit_width = _width, \
>                                 .div_table = _div_table, \
>                         }, \
>                 }, \
>         }
> struct ast2700_clk_info {
>         const char *name;
>         u8 clk_idx;
>         u32 reg;
>         u32 type;
>         union {
>                 struct ast2700_clk_fixed_factor_data factor;
>                 struct ast2700_clk_fixed_rate_data rate;
>                 struct ast2700_clk_gate_data gate;
>                 struct ast2700_clk_div_data div;
>                 struct ast2700_clk_pll_data pll;
>                 struct ast2700_clk_mux_data mux;
>         } data;
> };
> 
> struct ast2700_clk_div_data {
>         const struct clk_div_table *div_table;
>         const struct clk_parent_data *parent;
>         u8 bit_shift;
>         u8 bit_width;
>         u32 reg;
> };
> 
> static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = {
> ...........................
>         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,

Can you also show what soc0_ahbmux is?

>                     SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
> ......................
> > 
> > >
> > > >
> > > > > +       const struct clk_div_table *div_table;
> > > > > +       unsigned long fixed_rate;
> > > > > +       unsigned int mult;
> > > > > +       unsigned int div;
> > > > > +       u32 reg;
> > > > > +       u32 flags;
> > > > > +       u32 type;
> > > > > +       u8 clk_idx;
> > > > > +       u8 bit_shift;
> > > > > +       u8 bit_width;
> > > > > +       u8 num_parents;
> > > > > +};
> > > > > +
> > > > [...]
> > > > > +
> > > > > +static const struct clk_div_table ast2700_clk_div_table2[] = {
> > > > > +       { 0x0, 2 },
> > > > > +       { 0x1, 4 },
> > > > > +       { 0x2, 6 },
> > > > > +       { 0x3, 8 },
> > > > > +       { 0x4, 10 },
> > > > > +       { 0x5, 12 },
> > > > > +       { 0x6, 14 },
> > > > > +       { 0x7, 16 },
> > > >
> > > > Isn't this the default divider setting for struct clk_divider?
> > > Sorry, I don't catch your point.
> > > the SoC do have default divider setting. But it can be modified.
> > > And also have different divider table setting.
> > 
> > I mean that this is the way that struct clk_divider works already. So you don't
> > need to make the clk_div_table array for what is supported in code.
> 
> Sorry, I understand your point. But I trace the code didn't get any clue. "clk_divider work already".
> finally function call will be __clk_hw_register_divider
> https://github.com/torvalds/linux/blob/master/drivers/clk/clk-divider.c#L589
> It still need table point need to address. Can you give me more direction or example?
> 

The 'table' member is optional. When the table is NULL, we treat each
number that fits into the divider field width as a divider. It may be
CLK_DIVIDER_EVEN_INTEGERS that you have here though.


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

* RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-12-04 23:24           ` Stephen Boyd
@ 2024-12-05  0:48             ` Ryan Chen
  2024-12-06 22:15               ` Stephen Boyd
  0 siblings, 1 reply; 14+ messages in thread
From: Ryan Chen @ 2024-12-05  0:48 UTC (permalink / raw)
  To: Stephen Boyd, andrew@codeconstruct.com.au, conor+dt@kernel.org,
	devicetree@vger.kernel.org, dmitry.baryshkov@linaro.org,
	joel@jms.id.au, krzk+dt@kernel.org, lee@kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org, linux-clk@vger.kernel.org,
	linux-kernel@vger.kernel.org, mturquette@baylibre.com,
	p.zabel@pengutronix.de, robh@kernel.org

> Subject: RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> 
> Quoting Ryan Chen (2024-12-01 19:12:01)
> > > > > Subject: Re: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> > > > >
> > > > > Quoting Ryan Chen (2024-10-27 22:30:18)
> > > > > > diff --git a/drivers/clk/clk-ast2700.c
> > > > > > b/drivers/clk/clk-ast2700.c new file mode 100644 index
> > > > > > 000000000000..db9ee5031b7c
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/clk/clk-ast2700.c
> > > > > > @@ -0,0 +1,1513 @@
> > > > > > +// SPDX-License-Identifier: GPL-2.0
> > > [...]
> > > > > > +struct ast2700_clk_info {
> > > > > > +       const char *name;
> > > > > > +       const char * const *parent_names;
> > > > >
> > > > > Please don't use strings for parent names.
> > > > Sorry, do you mean use clk_parent_data struct for parent?
> > > >         +const struct clk_parent_data   parent;         /* For
> gate */
> > > >         +const struct clk_parent_data   *parents;
> /*
> > > For mux */
> > >
> > > Yes.
> > And I find a better way for parent_data. The following is my modification.
> > And parent_data will be union data structure. Like following.
> > Is this good direction?
> 
> Looks OK.
> 
> >
> > #define DIVIDER_CLK(_id, _name, _parent, _reg, _shift, _width, _div_table) \
> >         [_id] = { \
> >                 .type = CLK_DIVIDER, \
> >                 .name = _name, \
> >                 .data = { \
> >                         .div = { \
> >                                 .parent = _parent, \
> >                                 .reg = _reg, \
> >                                 .bit_shift = _shift, \
> >                                 .bit_width = _width, \
> >                                 .div_table = _div_table, \
> >                         }, \
> >                 }, \
> >         }
> > struct ast2700_clk_info {
> >         const char *name;
> >         u8 clk_idx;
> >         u32 reg;
> >         u32 type;
> >         union {
> >                 struct ast2700_clk_fixed_factor_data factor;
> >                 struct ast2700_clk_fixed_rate_data rate;
> >                 struct ast2700_clk_gate_data gate;
> >                 struct ast2700_clk_div_data div;
> >                 struct ast2700_clk_pll_data pll;
> >                 struct ast2700_clk_mux_data mux;
> >         } data;
> > };
> >
> > struct ast2700_clk_div_data {
> >         const struct clk_div_table *div_table;
> >         const struct clk_parent_data *parent;
> >         u8 bit_shift;
> >         u8 bit_width;
> >         u32 reg;
> > };
> >
> > static const struct ast2700_clk_info ast2700_scu0_clk_info[]
> > __initconst = { ...........................
> >         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
> 
> Can you also show what soc0_ahbmux is?
It will be following. 

static const struct clk_parent_data soc0_ahbmux[] = {
	{ .fw_name = "soc0-ahbmux", .name = "soc0-ahbmux" },
};
> 
> >                     SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
> > ......................
> > >
> > > >
> > > > >
> > > > > > +       const struct clk_div_table *div_table;
> > > > > > +       unsigned long fixed_rate;
> > > > > > +       unsigned int mult;
> > > > > > +       unsigned int div;
> > > > > > +       u32 reg;
> > > > > > +       u32 flags;
> > > > > > +       u32 type;
> > > > > > +       u8 clk_idx;
> > > > > > +       u8 bit_shift;
> > > > > > +       u8 bit_width;
> > > > > > +       u8 num_parents;
> > > > > > +};
> > > > > > +
> > > > > [...]
> > > > > > +
> > > > > > +static const struct clk_div_table ast2700_clk_div_table2[] = {
> > > > > > +       { 0x0, 2 },
> > > > > > +       { 0x1, 4 },
> > > > > > +       { 0x2, 6 },
> > > > > > +       { 0x3, 8 },
> > > > > > +       { 0x4, 10 },
> > > > > > +       { 0x5, 12 },
> > > > > > +       { 0x6, 14 },
> > > > > > +       { 0x7, 16 },
> > > > >
> > > > > Isn't this the default divider setting for struct clk_divider?
> > > > Sorry, I don't catch your point.
> > > > the SoC do have default divider setting. But it can be modified.
> > > > And also have different divider table setting.
> > >
> > > I mean that this is the way that struct clk_divider works already.
> > > So you don't need to make the clk_div_table array for what is supported in
> code.
> >
> > Sorry, I understand your point. But I trace the code didn't get any clue.
> "clk_divider work already".
> > finally function call will be __clk_hw_register_divider
> > https://github.com/torvalds/linux/blob/master/drivers/clk/clk-divider.
> > c#L589 It still need table point need to address. Can you give me more
> > direction or example?
> >
> 
> The 'table' member is optional. When the table is NULL, we treat each
> number that fits into the divider field width as a divider. It may be
> CLK_DIVIDER_EVEN_INTEGERS that you have here though.

Got it, will use this flag.

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

* RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-12-05  0:48             ` Ryan Chen
@ 2024-12-06 22:15               ` Stephen Boyd
  2024-12-09  1:49                 ` Ryan Chen
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Boyd @ 2024-12-06 22:15 UTC (permalink / raw)
  To: Ryan Chen, andrew, conor+dt, devicetree, dmitry.baryshkov, joel,
	krzk+dt, lee, linux-arm-kernel, linux-aspeed, linux-clk,
	linux-kernel, mturquette, p.zabel, robh

Quoting Ryan Chen (2024-12-04 16:48:42)
> > > struct ast2700_clk_info {
> > >         const char *name;
> > >         u8 clk_idx;
> > >         u32 reg;
> > >         u32 type;
> > >         union {
> > >                 struct ast2700_clk_fixed_factor_data factor;
> > >                 struct ast2700_clk_fixed_rate_data rate;
> > >                 struct ast2700_clk_gate_data gate;
> > >                 struct ast2700_clk_div_data div;
> > >                 struct ast2700_clk_pll_data pll;
> > >                 struct ast2700_clk_mux_data mux;
> > >         } data;
> > > };
> > >
> > > struct ast2700_clk_div_data {
> > >         const struct clk_div_table *div_table;
> > >         const struct clk_parent_data *parent;
> > >         u8 bit_shift;
> > >         u8 bit_width;
> > >         u32 reg;
> > > };
> > >
> > > static const struct ast2700_clk_info ast2700_scu0_clk_info[]
> > > __initconst = { ...........................
> > >         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
> > 
> > Can you also show what soc0_ahbmux is?
> It will be following. 
> 
> static const struct clk_parent_data soc0_ahbmux[] = {
>         { .fw_name = "soc0-ahbmux", .name = "soc0-ahbmux" },
> };

Instead of that, please use only the index.

 static const struct clk_parent_data soc0_ahbmux[] = {
         { .index = <number from DT binding> },
 };


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

* RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
  2024-12-06 22:15               ` Stephen Boyd
@ 2024-12-09  1:49                 ` Ryan Chen
  0 siblings, 0 replies; 14+ messages in thread
From: Ryan Chen @ 2024-12-09  1:49 UTC (permalink / raw)
  To: Stephen Boyd, andrew@codeconstruct.com.au, conor+dt@kernel.org,
	devicetree@vger.kernel.org, dmitry.baryshkov@linaro.org,
	joel@jms.id.au, krzk+dt@kernel.org, lee@kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-aspeed@lists.ozlabs.org, linux-clk@vger.kernel.org,
	linux-kernel@vger.kernel.org, mturquette@baylibre.com,
	p.zabel@pengutronix.de, robh@kernel.org

> Subject: RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> 
> Quoting Ryan Chen (2024-12-04 16:48:42)
> > > > struct ast2700_clk_info {
> > > >         const char *name;
> > > >         u8 clk_idx;
> > > >         u32 reg;
> > > >         u32 type;
> > > >         union {
> > > >                 struct ast2700_clk_fixed_factor_data factor;
> > > >                 struct ast2700_clk_fixed_rate_data rate;
> > > >                 struct ast2700_clk_gate_data gate;
> > > >                 struct ast2700_clk_div_data div;
> > > >                 struct ast2700_clk_pll_data pll;
> > > >                 struct ast2700_clk_mux_data mux;
> > > >         } data;
> > > > };
> > > >
> > > > struct ast2700_clk_div_data {
> > > >         const struct clk_div_table *div_table;
> > > >         const struct clk_parent_data *parent;
> > > >         u8 bit_shift;
> > > >         u8 bit_width;
> > > >         u32 reg;
> > > > };
> > > >
> > > > static const struct ast2700_clk_info ast2700_scu0_clk_info[]
> > > > __initconst = { ...........................
> > > >         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
> > >
> > > Can you also show what soc0_ahbmux is?
> > It will be following.
> >
> > static const struct clk_parent_data soc0_ahbmux[] = {
> >         { .fw_name = "soc0-ahbmux", .name = "soc0-ahbmux" }, };
> 
> Instead of that, please use only the index.
> 
>  static const struct clk_parent_data soc0_ahbmux[] = {
>          { .index = <number from DT binding> },  };

Sorry, if I use index instead, It can’t get parent data name for devm_clk_hw_register_fixed_factor parent_name parameters.
Does there have reference driver use index implement?

In probe function I implement for function for each clk register.
For example CLK_DIVIDER
Use div->parent->name get parent name for parameter.
			hws[i] = devm_clk_hw_register_divider_table(dev, clk->name,
								    div->parent->name, 0,
								    reg, div->bit_shift,
								    div->bit_width, 0,
								    div->div_table,
								    &clk_ctrl->lock);

Full implement is following.

	for (i = 0; i < clk_data->nr_clks; i++) {
		const struct ast2700_clk_info *clk = &clk_data->clk_info[i];
		void __iomem *reg = clk_ctrl->base + clk->reg;

		if (clk->type == CLK_FIXED) {
			const struct ast2700_clk_fixed_rate_data *fixed_rate = &clk->data.rate;

			hws[i] = devm_clk_hw_register_fixed_rate(dev, clk->name, NULL, 0,
								 fixed_rate->fixed_rate);
		} else if (clk->type == CLK_FIXED_FACTOR) {
			const struct ast2700_clk_fixed_factor_data *factor = &clk->data.factor;

			hws[i] = devm_clk_hw_register_fixed_factor(dev, clk->name,
								   factor->parent->name,
								   0, factor->mult, factor->div);
		} else if (clk->type == DCLK_FIXED) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_dclk(i, reg, clk->name, clk_ctrl);
		} else if (clk->type == CLK_HPLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_hpll(i, reg, clk->name,
							      pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_PLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_pll(i, reg, clk->name,
							     pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_UART_PLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_uartpll(i, reg, clk->name,
								 pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_MUX) {
			const struct ast2700_clk_mux_data *mux = &clk->data.mux;

			reg = clk_ctrl->base + mux->reg;
			hws[i] = devm_clk_hw_register_mux_parent_data_table(dev, clk->name,
									    mux->parents,
									    mux->num_parents, 0,
									    reg, mux->bit_shift,
									    mux->bit_width, 0,
									    NULL, &clk_ctrl->lock);
		} else if (clk->type == CLK_MISC) {
			const struct ast2700_clk_pll_data *misc = &clk->data.pll;

			reg = clk_ctrl->base + misc->reg;
			hws[i] = ast2700_clk_hw_register_misc(i, reg, clk->name,
							      misc->parent->name, clk_ctrl);
		} else if (clk->type == CLK_DIVIDER) {
			const struct ast2700_clk_div_data *div = &clk->data.div;

			reg = clk_ctrl->base + div->reg;
			hws[i] = devm_clk_hw_register_divider_table(dev, clk->name,
								    div->parent->name, 0,
								    reg, div->bit_shift,
								    div->bit_width, 0,
								    div->div_table,
								    &clk_ctrl->lock);
		} else if (clk->type == CLK_GATE_ASPEED) {
			const struct ast2700_clk_gate_data *gate = &clk->data.gate;

			reg = clk_ctrl->base + gate->reg;
			hws[i] = ast2700_clk_hw_register_gate(dev, clk->name, gate->parent,
							      reg, gate->bit, gate->flags, 0);

		} else {
			const struct ast2700_clk_gate_data *gate = &clk->data.gate;

			reg = clk_ctrl->base + gate->reg;
			hws[i] = devm_clk_hw_register_gate_parent_data(dev, clk->name, gate->parent,
								       0, reg, clk->clk_idx, 0,
								       &clk_ctrl->lock);
		}

		if (IS_ERR(hws[i]))
			return PTR_ERR(hws[i]);
	}

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

end of thread, other threads:[~2024-12-09  1:51 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-28  5:30 [PATCH v7 0/3] [PATCH v6 0/3] Add support for AST2700 clk driver Ryan Chen
2024-10-28  5:30 ` [PATCH v7 1/3] dt-bindings: mfd: aspeed: support for AST2700 Ryan Chen
2024-10-28  5:30 ` [PATCH v7 2/3] reset: aspeed: register AST2700 reset auxiliary bus device Ryan Chen
2024-10-28  5:30 ` [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver Ryan Chen
2024-10-30 21:01   ` Stephen Boyd
2024-10-31  7:24     ` Ryan Chen
2024-11-21 23:06       ` Stephen Boyd
2024-12-02  3:12         ` Ryan Chen
2024-12-04 23:24           ` Stephen Boyd
2024-12-05  0:48             ` Ryan Chen
2024-12-06 22:15               ` Stephen Boyd
2024-12-09  1:49                 ` Ryan Chen
2024-10-30 21:02   ` Stephen Boyd
2024-10-31  0:44   ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).