* [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller
@ 2024-06-24 2:12 Drew Fustini
2024-06-24 2:12 ` [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller Drew Fustini
` (6 more replies)
0 siblings, 7 replies; 15+ messages in thread
From: Drew Fustini @ 2024-06-24 2:12 UTC (permalink / raw)
To: Jisheng Zhang, Guo Ren, Fu Wei, Yangtao Li, Thomas Bonnefille,
Emil Renner Berthing, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini,
Conor Dooley
This series adds support for the AP sub-system clock controller in the
T-Head TH1520 [1]. Yangtao Li originally submitted this series in May
2023 [2]. Jisheng made additional improvements and then passed on the
work in progress to me.
Changes in v2:
- Add clock property to the gpio nodes after Conor asked why they were
missing. These clock gates correspond to enable bits in PERI_CLK_CFG.
- Drop 2 cell address and size properties from the binding example per
Conor and add Reviewed-by from from Conor.
Changes in v1:
- Split th1520_clks into groups for gate, mux, div, pll
- Convert gate clocks to devm_clk_hw_register_gate_parent_data()
- Convert mux clocks to devm_clk_hw_register_mux_parent_data_table()
- Split the PLL recalculation into th1520_pll_vco_recalc_rate() and
th1520_pll_postdiv_recalc_rate(). Based on Emil's comments in v1,
add logic to handle the fractional portion of feedback divide value
when the delta-sigma modulator (DSM) is active.
- Drop clock-names from the binding per Stephan to avoid relying on
anything other than the cell index when describing clk_parent_data
(note: I dropped Rob's Rb because I changed the binding patch)
- Rename reg/reg2 to cfg0/cfg1 to match the SoC documentation
- Rename struct for pll clocks from ccu_mdiv to ccu_pll
- Rebase on v6.10-rc3, remove the dts node reordering patch from v3
now that it is in mainline
Changes in RFC v3 [3]:
- Drop redundant new line and unused clk label from the dts example in
the DT binding which I failed to fix in v2.
- Add patch [4] from Thomas Bonnefille that fixes dts node ordering in
th1520.dtsi. Conor has already merged it into riscv-dt-for-next so
the dts patches in this series are based on top of that.
- Remove fixed uart clock and converted uart DT nodes to use clocks
from the clock controller.
- Remove fixed apb clock and converted the dma controller and timer DT
nodes to use a clock from the clock controller.
- Made ccu_disable_helper() and ccu_enable_helper() to static functions
- Follow the advice from Stephen Boyd in Yangtao's original series to
not use strings for clk tree topology. Created clk_parent_data arrays
to be used with CLK_HW_INIT_PARENTS_DATA instead of parent strings.
- Rebase on top of v6.9-rc7
Changes in RFC v2 [5]:
- squash the header file patch into the DT schema patch
- describe the changes I made to original series in the cover letter
instead of the individual patches
- fix my typo in my email address
Changes in RFC v1 [6] from the original series:
- corrected the npu_clk enable bit
- deduplicated CLK_NPU and CLK_NPU_AXI number in header
- fixed c910_i0_clk reg typo
- fixed checkpatch and dt_binding_check warnings
- rebased on v6.9-rc5
- revised commit descriptions
Thank you,
Drew
[1] https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
[2] https://lore.kernel.org/all/20230515054402.27633-1-frank.li@vivo.com/
[3] https://lore.kernel.org/all/20240506-th1520-clk-v3-0-085a18a23a7f@tenstorrent.com/
[4] https://lore.kernel.org/all/20240425082138.374445-1-thomas.bonnefille@bootlin.com/
[5] https://lore.kernel.org/all/20240426-th1520-clk-v2-v2-0-96b829e6fcee@tenstorrent.com/
[6] https://lore.kernel.org/all/20240110-clk-th1520-v1-0-8b0682567984@tenstorrent.com/
To: Jisheng Zhang <jszhang@kernel.org>
To: Guo Ren <guoren@kernel.org>
To: Fu Wei <wefu@redhat.com>
To: Yangtao Li <frank.li@vivo.com>
To: Thomas Bonnefille <thomas.bonnefille@bootlin.com>
To: Emil Renner Berthing <emil.renner.berthing@canonical.com>
To: Michael Turquette <mturquette@baylibre.com>
To: Stephen Boyd <sboyd@kernel.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Paul Walmsley <paul.walmsley@sifive.com>
To: Palmer Dabbelt <palmer@dabbelt.com>
To: Albert Ou <aou@eecs.berkeley.edu>
Cc: linux-riscv@lists.infradead.org
Cc: linux-clk@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
---
Drew Fustini (7):
dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller
clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks
riscv: dts: thead: Add TH1520 AP_SUBSYS clock controller
riscv: dts: thead: change TH1520 uart nodes to use clock controller
riscv: dts: thead: change TH1520 mmc nodes to use clock controller
riscv: dts: thead: update TH1520 dma and timer nodes to use clock controller
riscv: dts: thead: add clock to TH1520 gpio nodes
.../bindings/clock/thead,th1520-clk-ap.yaml | 53 +
MAINTAINERS | 3 +
arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts | 12 -
.../boot/dts/thead/th1520-lichee-module-4a.dtsi | 12 -
arch/riscv/boot/dts/thead/th1520.dtsi | 73 +-
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/thead/Kconfig | 12 +
drivers/clk/thead/Makefile | 2 +
drivers/clk/thead/clk-th1520-ap.c | 1086 ++++++++++++++++++++
include/dt-bindings/clock/thead,th1520-clk-ap.h | 96 ++
11 files changed, 1290 insertions(+), 61 deletions(-)
---
base-commit: 83a7eefedc9b56fe7bfeff13b6c7356688ffa670
change-id: 20240622-th1520-clk-e813a97b9e16
Best regards,
--
Drew Fustini <dfustini@tenstorrent.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller
2024-06-24 2:12 [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller Drew Fustini
@ 2024-06-24 2:12 ` Drew Fustini
2024-07-10 23:17 ` Stephen Boyd
2024-06-24 2:12 ` [PATCH v2 2/7] clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks Drew Fustini
` (5 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Drew Fustini @ 2024-06-24 2:12 UTC (permalink / raw)
To: Jisheng Zhang, Guo Ren, Fu Wei, Yangtao Li, Thomas Bonnefille,
Emil Renner Berthing, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini,
Conor Dooley
Document bindings for the T-Head TH1520 AP sub-system clock controller.
Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
Co-developed-by: Yangtao Li <frank.li@vivo.com>
Signed-off-by: Yangtao Li <frank.li@vivo.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
---
.../bindings/clock/thead,th1520-clk-ap.yaml | 53 ++++++++++++
MAINTAINERS | 2 +
include/dt-bindings/clock/thead,th1520-clk-ap.h | 96 ++++++++++++++++++++++
3 files changed, 151 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml b/Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
new file mode 100644
index 000000000000..0129bd0ba4b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/thead,th1520-clk-ap.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: T-HEAD TH1520 AP sub-system clock controller
+
+description: |
+ The T-HEAD TH1520 AP sub-system clock controller configures the
+ CPU, DPU, GMAC and TEE PLLs.
+
+ SoC reference manual
+ https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
+
+maintainers:
+ - Jisheng Zhang <jszhang@kernel.org>
+ - Wei Fu <wefu@redhat.com>
+ - Drew Fustini <dfustini@tenstorrent.com>
+
+properties:
+ compatible:
+ const: thead,th1520-clk-ap
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: main oscillator (24MHz)
+
+ "#clock-cells":
+ const: 1
+ description:
+ See <dt-bindings/clock/thead,th1520-clk-ap.h> for valid indices.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/thead,th1520-clk-ap.h>
+ clock-controller@ef010000 {
+ compatible = "thead,th1520-clk-ap";
+ reg = <0xef010000 0x1000>;
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index aacccb376c28..761fcbddc8d6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19320,7 +19320,9 @@ M: Guo Ren <guoren@kernel.org>
M: Fu Wei <wefu@redhat.com>
L: linux-riscv@lists.infradead.org
S: Maintained
+F: Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
F: arch/riscv/boot/dts/thead/
+F: include/dt-bindings/clock/thead,th1520-clk-ap.h
RNBD BLOCK DRIVERS
M: Md. Haris Iqbal <haris.iqbal@ionos.com>
diff --git a/include/dt-bindings/clock/thead,th1520-clk-ap.h b/include/dt-bindings/clock/thead,th1520-clk-ap.h
new file mode 100644
index 000000000000..a199784b3512
--- /dev/null
+++ b/include/dt-bindings/clock/thead,th1520-clk-ap.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2023 Vivo Communication Technology Co. Ltd.
+ * Authors: Yangtao Li <frank.li@vivo.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_TH1520_H_
+#define _DT_BINDINGS_CLK_TH1520_H_
+
+#define CLK_CPU_PLL0 0
+#define CLK_CPU_PLL1 1
+#define CLK_GMAC_PLL 2
+#define CLK_VIDEO_PLL 3
+#define CLK_DPU0_PLL 4
+#define CLK_DPU1_PLL 5
+#define CLK_TEE_PLL 6
+#define CLK_C910_I0 7
+#define CLK_C910 8
+#define CLK_BROM 9
+#define CLK_BMU 10
+#define CLK_AHB2_CPUSYS_HCLK 11
+#define CLK_APB3_CPUSYS_PCLK 12
+#define CLK_AXI4_CPUSYS2_ACLK 13
+#define CLK_AON2CPU_A2X 14
+#define CLK_X2X_CPUSYS 15
+#define CLK_AXI_ACLK 16
+#define CLK_CPU2AON_X2H 17
+#define CLK_PERI_AHB_HCLK 18
+#define CLK_CPU2PERI_X2H 19
+#define CLK_PERI_APB_PCLK 20
+#define CLK_PERI2APB_PCLK 21
+#define CLK_PERISYS_APB1_HCLK 22
+#define CLK_PERISYS_APB2_HCLK 23
+#define CLK_PERISYS_APB3_HCLK 24
+#define CLK_PERISYS_APB4_HCLK 25
+#define CLK_OSC12M 26
+#define CLK_OUT1 27
+#define CLK_OUT2 28
+#define CLK_OUT3 29
+#define CLK_OUT4 30
+#define CLK_APB_PCLK 31
+#define CLK_NPU 32
+#define CLK_NPU_AXI 33
+#define CLK_VI 34
+#define CLK_VI_AHB 35
+#define CLK_VO_AXI 36
+#define CLK_VP_APB 37
+#define CLK_VP_AXI 38
+#define CLK_CPU2VP 39
+#define CLK_VENC 40
+#define CLK_DPU0 41
+#define CLK_DPU1 42
+#define CLK_EMMC_SDIO 43
+#define CLK_GMAC1 44
+#define CLK_PADCTRL1 45
+#define CLK_DSMART 46
+#define CLK_PADCTRL0 47
+#define CLK_GMAC_AXI 48
+#define CLK_GPIO3 49
+#define CLK_GMAC0 50
+#define CLK_PWM 51
+#define CLK_QSPI0 52
+#define CLK_QSPI1 53
+#define CLK_SPI 54
+#define CLK_UART0_PCLK 55
+#define CLK_UART1_PCLK 56
+#define CLK_UART2_PCLK 57
+#define CLK_UART3_PCLK 58
+#define CLK_UART4_PCLK 59
+#define CLK_UART5_PCLK 60
+#define CLK_GPIO0 61
+#define CLK_GPIO1 62
+#define CLK_GPIO2 63
+#define CLK_I2C0 64
+#define CLK_I2C1 65
+#define CLK_I2C2 66
+#define CLK_I2C3 67
+#define CLK_I2C4 68
+#define CLK_I2C5 69
+#define CLK_SPINLOCK 70
+#define CLK_DMA 71
+#define CLK_MBOX0 72
+#define CLK_MBOX1 73
+#define CLK_MBOX2 74
+#define CLK_MBOX3 75
+#define CLK_WDT0 76
+#define CLK_WDT1 77
+#define CLK_TIMER0 78
+#define CLK_TIMER1 79
+#define CLK_SRAM0 80
+#define CLK_SRAM1 81
+#define CLK_SRAM2 82
+#define CLK_SRAM3 83
+#define CLK_PLL_GMAC_100M 84
+#define CLK_UART_SCLK 85
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 2/7] clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks
2024-06-24 2:12 [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller Drew Fustini
2024-06-24 2:12 ` [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller Drew Fustini
@ 2024-06-24 2:12 ` Drew Fustini
2024-07-10 23:17 ` Stephen Boyd
2024-06-24 2:12 ` [PATCH v2 3/7] riscv: dts: thead: Add TH1520 AP_SUBSYS clock controller Drew Fustini
` (4 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Drew Fustini @ 2024-06-24 2:12 UTC (permalink / raw)
To: Jisheng Zhang, Guo Ren, Fu Wei, Yangtao Li, Thomas Bonnefille,
Emil Renner Berthing, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini
Add support for the AP sub-system clock controller in the T-Head TH1520.
This include CPU, DPU, GMAC and TEE PLLs.
Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
Co-developed-by: Yangtao Li <frank.li@vivo.com>
Signed-off-by: Yangtao Li <frank.li@vivo.com>
Co-developed-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
---
MAINTAINERS | 1 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/thead/Kconfig | 12 +
drivers/clk/thead/Makefile | 2 +
drivers/clk/thead/clk-th1520-ap.c | 1086 +++++++++++++++++++++++++++++++++++++
6 files changed, 1103 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 761fcbddc8d6..75880648dd14 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19322,6 +19322,7 @@ L: linux-riscv@lists.infradead.org
S: Maintained
F: Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml
F: arch/riscv/boot/dts/thead/
+F: drivers/clk/thead/clk-th1520-ap.c
F: include/dt-bindings/clock/thead,th1520-clk-ap.h
RNBD BLOCK DRIVERS
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 3e9099504fad..d73ae04e427a 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -495,6 +495,7 @@ source "drivers/clk/starfive/Kconfig"
source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/sunxi-ng/Kconfig"
source "drivers/clk/tegra/Kconfig"
+source "drivers/clk/thead/Kconfig"
source "drivers/clk/stm32/Kconfig"
source "drivers/clk/ti/Kconfig"
source "drivers/clk/uniphier/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 4abe16c8ccdf..f793a16cad40 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -127,6 +127,7 @@ obj-y += starfive/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-y += sunxi-ng/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
+obj-$(CONFIG_ARCH_THEAD) += thead/
obj-y += ti/
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
obj-$(CONFIG_ARCH_U8500) += ux500/
diff --git a/drivers/clk/thead/Kconfig b/drivers/clk/thead/Kconfig
new file mode 100644
index 000000000000..1710d50bf9d4
--- /dev/null
+++ b/drivers/clk/thead/Kconfig
@@ -0,0 +1,12 @@
+#SPDX-License-Identifier: GPL-2.0
+
+config CLK_THEAD_TH1520_AP
+ bool "T-HEAD TH1520 AP clock support"
+ depends on ARCH_THEAD || COMPILE_TEST
+ default ARCH_THEAD
+ select REGMAP_MMIO
+ help
+ Say yes here to support the AP sub system clock controller
+ on the T-HEAD TH1520 SoC. This includes configuration of
+ both CPU PLLs, both DPU PLLs as well as the GMAC, VIDEO,
+ and TEE PLLs.
diff --git a/drivers/clk/thead/Makefile b/drivers/clk/thead/Makefile
new file mode 100644
index 000000000000..7ee0bec1f251
--- /dev/null
+++ b/drivers/clk/thead/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_CLK_THEAD_TH1520_AP) += clk-th1520-ap.o
diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c
new file mode 100644
index 000000000000..982d4d40f783
--- /dev/null
+++ b/drivers/clk/thead/clk-th1520-ap.c
@@ -0,0 +1,1086 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
+ * Copyright (C) 2023 Vivo Communication Technology Co. Ltd.
+ * Authors: Yangtao Li <frank.li@vivo.com>
+ */
+
+#include <dt-bindings/clock/thead,th1520-clk-ap.h>
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define TH1520_PLL_POSTDIV2 GENMASK(26, 24)
+#define TH1520_PLL_POSTDIV1 GENMASK(22, 20)
+#define TH1520_PLL_FBDIV GENMASK(19, 8)
+#define TH1520_PLL_REFDIV GENMASK(5, 0)
+#define TH1520_PLL_BYPASS BIT(30)
+#define TH1520_PLL_DSMPD BIT(24)
+#define TH1520_PLL_FRAC GENMASK(23, 0)
+#define TH1520_PLL_FRAC_BITS 24
+
+struct ccu_internal {
+ u8 shift;
+ u8 width;
+};
+
+struct ccu_div_internal {
+ u8 shift;
+ u8 width;
+ u32 flags;
+};
+
+struct ccu_common {
+ int clkid;
+ struct regmap *map;
+ u16 cfg0;
+ u16 cfg1;
+ struct clk_hw hw;
+};
+
+struct ccu_mux {
+ struct ccu_internal mux;
+ struct ccu_common common;
+};
+
+struct ccu_gate {
+ u32 enable;
+ struct ccu_common common;
+};
+
+struct ccu_div {
+ u32 enable;
+ struct ccu_div_internal div;
+ struct ccu_internal mux;
+ struct ccu_common common;
+};
+
+struct ccu_pll {
+ struct ccu_common common;
+};
+
+#define TH_CCU_ARG(_shift, _width) \
+ { \
+ .shift = _shift, \
+ .width = _width, \
+ }
+
+#define TH_CCU_DIV_FLAGS(_shift, _width, _flags) \
+ { \
+ .shift = _shift, \
+ .width = _width, \
+ .flags = _flags, \
+ }
+
+#define CCU_GATE(_clkid, _struct, _name, _parent, _reg, _gate, _flags) \
+ struct ccu_gate _struct = { \
+ .enable = _gate, \
+ .common = { \
+ .clkid = _clkid, \
+ .cfg0 = _reg, \
+ .hw.init = CLK_HW_INIT_PARENTS_DATA( \
+ _name, \
+ _parent, \
+ &clk_gate_ops, \
+ _flags), \
+ } \
+ }
+
+static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw)
+{
+ return container_of(hw, struct ccu_common, hw);
+}
+
+static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
+{
+ struct ccu_common *common = hw_to_ccu_common(hw);
+
+ return container_of(common, struct ccu_mux, common);
+}
+
+static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw)
+{
+ struct ccu_common *common = hw_to_ccu_common(hw);
+
+ return container_of(common, struct ccu_pll, common);
+}
+
+static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
+{
+ struct ccu_common *common = hw_to_ccu_common(hw);
+
+ return container_of(common, struct ccu_div, common);
+}
+
+static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw)
+{
+ struct ccu_common *common = hw_to_ccu_common(hw);
+
+ return container_of(common, struct ccu_gate, common);
+}
+
+static u8 ccu_get_parent_helper(struct ccu_common *common,
+ struct ccu_internal *mux)
+{
+ unsigned int val;
+ u8 parent;
+
+ regmap_read(common->map, common->cfg0, &val);
+ parent = val >> mux->shift;
+ parent &= GENMASK(mux->width - 1, 0);
+
+ return parent;
+}
+
+static int ccu_set_parent_helper(struct ccu_common *common,
+ struct ccu_internal *mux,
+ u8 index)
+{
+ return regmap_update_bits(common->map, common->cfg0,
+ GENMASK(mux->width - 1, 0) << mux->shift,
+ index << mux->shift);
+}
+
+static void ccu_disable_helper(struct ccu_common *common, u32 gate)
+{
+ if (!gate)
+ return;
+ regmap_update_bits(common->map, common->cfg0,
+ gate, ~gate);
+}
+
+static int ccu_enable_helper(struct ccu_common *common, u32 gate)
+{
+ unsigned int val;
+ int ret;
+
+ if (!gate)
+ return 0;
+
+ ret = regmap_update_bits(common->map, common->cfg0, gate, gate);
+ regmap_read(common->map, common->cfg0, &val);
+ return ret;
+}
+
+static int ccu_is_enabled_helper(struct ccu_common *common, u32 gate)
+{
+ unsigned int val;
+
+ if (!gate)
+ return true;
+
+ regmap_read(common->map, common->cfg0, &val);
+ return val & gate;
+}
+
+static unsigned long ccu_div_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ccu_div *cd = hw_to_ccu_div(hw);
+ unsigned long rate;
+ unsigned int val;
+
+ regmap_read(cd->common.map, cd->common.cfg0, &val);
+ val = val >> cd->div.shift;
+ val &= GENMASK(cd->div.width - 1, 0);
+ rate = divider_recalc_rate(hw, parent_rate, val, NULL,
+ cd->div.flags, cd->div.width);
+
+ return rate;
+}
+
+static u8 ccu_div_get_parent(struct clk_hw *hw)
+{
+ struct ccu_div *cd = hw_to_ccu_div(hw);
+
+ return ccu_get_parent_helper(&cd->common, &cd->mux);
+}
+
+static int ccu_div_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct ccu_div *cd = hw_to_ccu_div(hw);
+
+ return ccu_set_parent_helper(&cd->common, &cd->mux, index);
+}
+
+static void ccu_div_disable(struct clk_hw *hw)
+{
+ struct ccu_div *cd = hw_to_ccu_div(hw);
+
+ ccu_disable_helper(&cd->common, cd->enable);
+}
+
+static int ccu_div_enable(struct clk_hw *hw)
+{
+ struct ccu_div *cd = hw_to_ccu_div(hw);
+
+ return ccu_enable_helper(&cd->common, cd->enable);
+}
+
+static int ccu_div_is_enabled(struct clk_hw *hw)
+{
+ struct ccu_div *cd = hw_to_ccu_div(hw);
+
+ return ccu_is_enabled_helper(&cd->common, cd->enable);
+}
+
+static const struct clk_ops ccu_div_ops = {
+ .disable = ccu_div_disable,
+ .enable = ccu_div_enable,
+ .is_enabled = ccu_div_is_enabled,
+ .get_parent = ccu_div_get_parent,
+ .set_parent = ccu_div_set_parent,
+ .recalc_rate = ccu_div_recalc_rate,
+ .determine_rate = clk_hw_determine_rate_no_reparent,
+};
+
+static unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ccu_pll *pll = hw_to_ccu_pll(hw);
+ unsigned long div, mul, frac, rate = parent_rate;
+ unsigned int cfg0, cfg1;
+
+ regmap_read(pll->common.map, pll->common.cfg0, &cfg0);
+ regmap_read(pll->common.map, pll->common.cfg1, &cfg1);
+
+ mul = FIELD_GET(TH1520_PLL_FBDIV, cfg0);
+ div = FIELD_GET(TH1520_PLL_REFDIV, cfg0);
+ if (!(cfg1 & TH1520_PLL_DSMPD)) {
+ mul <<= TH1520_PLL_FRAC_BITS;
+ frac = FIELD_GET(TH1520_PLL_FRAC, cfg1);
+ mul += frac;
+ div <<= TH1520_PLL_FRAC_BITS;
+ }
+ rate = parent_rate * mul;
+ do_div(rate, div);
+ return rate;
+}
+
+static unsigned long th1520_pll_postdiv_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ccu_pll *pll = hw_to_ccu_pll(hw);
+ unsigned long rate = parent_rate;
+ unsigned int cfg0, cfg1;
+
+ regmap_read(pll->common.map, pll->common.cfg0, &cfg0);
+ regmap_read(pll->common.map, pll->common.cfg1, &cfg1);
+
+ if (cfg1 & TH1520_PLL_BYPASS)
+ return rate;
+
+ do_div(rate, FIELD_GET(TH1520_PLL_POSTDIV1, cfg0) *
+ FIELD_GET(TH1520_PLL_POSTDIV2, cfg0));
+
+ return rate;
+}
+
+static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ unsigned long rate = parent_rate;
+
+ rate = th1520_pll_vco_recalc_rate(hw, rate);
+ rate = th1520_pll_postdiv_recalc_rate(hw, rate);
+
+ return rate;
+}
+
+static const struct clk_ops clk_pll_ops = {
+ .recalc_rate = ccu_pll_recalc_rate,
+};
+
+static const struct clk_parent_data osc_24m_clk[] = {
+ { .index = 0 }
+};
+
+static struct ccu_pll cpu_pll0_clk = {
+ .common = {
+ .clkid = CLK_CPU_PLL0,
+ .cfg0 = 0x000,
+ .cfg1 = 0x004,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("cpu-pll0",
+ osc_24m_clk,
+ &clk_pll_ops,
+ 0),
+ },
+};
+
+static struct ccu_pll cpu_pll1_clk = {
+ .common = {
+ .clkid = CLK_CPU_PLL1,
+ .cfg0 = 0x010,
+ .cfg1 = 0x014,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("cpu-pll1",
+ osc_24m_clk,
+ &clk_pll_ops,
+ 0),
+ },
+};
+
+static struct ccu_pll gmac_pll_clk = {
+ .common = {
+ .clkid = CLK_GMAC_PLL,
+ .cfg0 = 0x020,
+ .cfg1 = 0x024,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("gmac-pll",
+ osc_24m_clk,
+ &clk_pll_ops,
+ 0),
+ },
+};
+
+static const struct clk_hw *gmac_pll_clk_parent[] = {
+ &gmac_pll_clk.common.hw
+};
+
+static const struct clk_parent_data gmac_pll_clk_pd[] = {
+ { .hw = &gmac_pll_clk.common.hw }
+};
+
+static struct ccu_pll video_pll_clk = {
+ .common = {
+ .clkid = CLK_VIDEO_PLL,
+ .cfg0 = 0x030,
+ .cfg1 = 0x034,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("video-pll",
+ osc_24m_clk,
+ &clk_pll_ops,
+ 0),
+ },
+};
+
+static const struct clk_hw *video_pll_clk_parent[] = {
+ &video_pll_clk.common.hw
+};
+
+static const struct clk_parent_data video_pll_clk_pd[] = {
+ { .hw = &video_pll_clk.common.hw }
+};
+
+static struct ccu_pll dpu0_pll_clk = {
+ .common = {
+ .clkid = CLK_DPU0_PLL,
+ .cfg0 = 0x040,
+ .cfg1 = 0x044,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("dpu0-pll",
+ osc_24m_clk,
+ &clk_pll_ops,
+ 0),
+ },
+};
+
+static const struct clk_hw *dpu0_pll_clk_parent[] = {
+ &dpu0_pll_clk.common.hw
+};
+
+static struct ccu_pll dpu1_pll_clk = {
+ .common = {
+ .clkid = CLK_DPU1_PLL,
+ .cfg0 = 0x050,
+ .cfg1 = 0x054,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("dpu1-pll",
+ osc_24m_clk,
+ &clk_pll_ops,
+ 0),
+ },
+};
+
+static const struct clk_hw *dpu1_pll_clk_parent[] = {
+ &dpu1_pll_clk.common.hw
+};
+
+static struct ccu_pll tee_pll_clk = {
+ .common = {
+ .clkid = CLK_TEE_PLL,
+ .cfg0 = 0x060,
+ .cfg1 = 0x064,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("tee-pll",
+ osc_24m_clk,
+ &clk_pll_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data c910_i0_parents[] = {
+ { .hw = &cpu_pll0_clk.common.hw },
+ { .index = 0 }
+};
+
+struct ccu_mux c910_i0_clk = {
+ .mux = TH_CCU_ARG(1, 1),
+ .common = {
+ .clkid = CLK_C910_I0,
+ .cfg0 = 0x100,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("c910-i0",
+ c910_i0_parents,
+ &clk_mux_ops,
+ 0),
+ }
+};
+
+static const struct clk_parent_data c910_parents[] = {
+ { .hw = &c910_i0_clk.common.hw },
+ { .hw = &cpu_pll1_clk.common.hw }
+};
+
+struct ccu_mux c910_clk = {
+ .mux = TH_CCU_ARG(0, 1),
+ .common = {
+ .clkid = CLK_C910,
+ .cfg0 = 0x100,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("c910",
+ c910_parents,
+ &clk_mux_ops,
+ 0),
+ }
+};
+
+static const struct clk_parent_data ahb2_cpusys_parents[] = {
+ { .hw = &gmac_pll_clk.common.hw },
+ { .index = 0 }
+};
+
+static struct ccu_div ahb2_cpusys_hclk = {
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(5, 1),
+ .common = {
+ .clkid = CLK_AHB2_CPUSYS_HCLK,
+ .cfg0 = 0x120,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("ahb2-cpusys-hclk",
+ ahb2_cpusys_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data ahb2_cpusys_hclk_pd[] = {
+ { .hw = &ahb2_cpusys_hclk.common.hw }
+};
+
+static const struct clk_hw *ahb2_cpusys_hclk_parent[] = {
+ &ahb2_cpusys_hclk.common.hw,
+};
+
+static struct ccu_div apb3_cpusys_pclk = {
+ .div = TH_CCU_ARG(0, 3),
+ .common = {
+ .clkid = CLK_APB3_CPUSYS_PCLK,
+ .cfg0 = 0x130,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("apb3-cpusys-pclk",
+ ahb2_cpusys_hclk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data apb3_cpusys_pclk_pd[] = {
+ { .hw = &apb3_cpusys_pclk.common.hw }
+};
+
+static struct ccu_div axi4_cpusys2_aclk = {
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_AXI4_CPUSYS2_ACLK,
+ .cfg0 = 0x134,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("axi4-cpusys2-aclk",
+ gmac_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data axi4_cpusys2_aclk_pd[] = {
+ { .hw = &axi4_cpusys2_aclk.common.hw }
+};
+
+static const struct clk_parent_data axi_parents[] = {
+ { .hw = &video_pll_clk.common.hw },
+ { .index = 0 }
+};
+
+static struct ccu_div axi_aclk = {
+ .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(5, 1),
+ .common = {
+ .clkid = CLK_AXI_ACLK,
+ .cfg0 = 0x138,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("axi-aclk",
+ axi_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data axi_aclk_pd[] = {
+ { .hw = &axi_aclk.common.hw }
+};
+
+static const struct clk_parent_data perisys_ahb_hclk_parents[] = {
+ { .hw = &gmac_pll_clk.common.hw },
+ { .index = 0 },
+};
+
+static struct ccu_div perisys_ahb_hclk = {
+ .enable = BIT(6),
+ .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(5, 1),
+ .common = {
+ .clkid = CLK_PERI_AHB_HCLK,
+ .cfg0 = 0x140,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("perisys-ahb-hclk",
+ perisys_ahb_hclk_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data perisys_ahb_hclk_pd[] = {
+ { .hw = &perisys_ahb_hclk.common.hw }
+};
+
+static const struct clk_hw *perisys_ahb_hclk_parent[] = {
+ &perisys_ahb_hclk.common.hw
+};
+
+static struct ccu_div perisys_apb_pclk = {
+ .div = TH_CCU_ARG(0, 3),
+ .common = {
+ .clkid = CLK_PERI_APB_PCLK,
+ .cfg0 = 0x150,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("perisys-apb-pclk",
+ perisys_ahb_hclk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data perisys_apb_pclk_pd[] = {
+ { .hw = &perisys_apb_pclk.common.hw }
+};
+
+static struct ccu_div peri2sys_apb_pclk = {
+ .div = TH_CCU_DIV_FLAGS(4, 3, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_PERI2APB_PCLK,
+ .cfg0 = 0x150,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("peri2sys-apb-pclk",
+ gmac_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data peri2sys_apb_pclk_pd[] = {
+ { .hw = &peri2sys_apb_pclk.common.hw }
+};
+
+static CLK_FIXED_FACTOR_FW_NAME(osc12m_clk, "osc_12m", "osc_24m", 2, 1, 0);
+
+static const char * const out_parents[] = { "osc_24m", "osc_12m" };
+
+static struct ccu_div out1_clk = {
+ .enable = BIT(5),
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(4, 1),
+ .common = {
+ .clkid = CLK_OUT1,
+ .cfg0 = 0x1b4,
+ .hw.init = CLK_HW_INIT_PARENTS("out1",
+ out_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div out2_clk = {
+ .enable = BIT(5),
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(4, 1),
+ .common = {
+ .clkid = CLK_OUT2,
+ .cfg0 = 0x1b8,
+ .hw.init = CLK_HW_INIT_PARENTS("out2",
+ out_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div out3_clk = {
+ .enable = BIT(5),
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(4, 1),
+ .common = {
+ .clkid = CLK_OUT3,
+ .cfg0 = 0x1bc,
+ .hw.init = CLK_HW_INIT_PARENTS("out3",
+ out_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div out4_clk = {
+ .enable = BIT(5),
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(4, 1),
+ .common = {
+ .clkid = CLK_OUT4,
+ .cfg0 = 0x1c0,
+ .hw.init = CLK_HW_INIT_PARENTS("out4",
+ out_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_parent_data apb_parents[] = {
+ { .hw = &gmac_pll_clk.common.hw },
+ { .index = 0 },
+};
+
+static struct ccu_div apb_pclk = {
+ .enable = BIT(5),
+ .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(7, 1),
+ .common = {
+ .clkid = CLK_APB_PCLK,
+ .cfg0 = 0x1c4,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("apb-pclk",
+ apb_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static const struct clk_hw *npu_parents[] = {
+ &gmac_pll_clk.common.hw,
+ &video_pll_clk.common.hw
+};
+
+static struct ccu_div npu_clk = {
+ .enable = BIT(4),
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .mux = TH_CCU_ARG(6, 1),
+ .common = {
+ .clkid = CLK_NPU,
+ .cfg0 = 0x1c8,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("npu",
+ npu_parents,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div vi_clk = {
+ .div = TH_CCU_DIV_FLAGS(16, 4, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_VI,
+ .cfg0 = 0x1d0,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vi",
+ video_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div vi_ahb_clk = {
+ .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_VI_AHB,
+ .cfg0 = 0x1d0,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vi-ahb",
+ video_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div vo_axi_clk = {
+ .enable = BIT(5),
+ .div = TH_CCU_DIV_FLAGS(0, 4, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_VO_AXI,
+ .cfg0 = 0x1dc,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vo-axi",
+ video_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div vp_apb_clk = {
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_VP_APB,
+ .cfg0 = 0x1e0,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vp-apb",
+ gmac_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div vp_axi_clk = {
+ .enable = BIT(15),
+ .div = TH_CCU_DIV_FLAGS(8, 4, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_VP_AXI,
+ .cfg0 = 0x1e0,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("vp-axi",
+ video_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div venc_clk = {
+ .enable = BIT(5),
+ .div = TH_CCU_DIV_FLAGS(0, 3, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_VENC,
+ .cfg0 = 0x1e4,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("venc",
+ gmac_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div dpu0_clk = {
+ .div = TH_CCU_DIV_FLAGS(0, 8, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_DPU0,
+ .cfg0 = 0x1e8,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("dpu0",
+ dpu0_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static struct ccu_div dpu1_clk = {
+ .div = TH_CCU_DIV_FLAGS(0, 8, CLK_DIVIDER_ONE_BASED),
+ .common = {
+ .clkid = CLK_DPU1,
+ .cfg0 = 0x1ec,
+ .hw.init = CLK_HW_INIT_PARENTS_HW("dpu1",
+ dpu1_pll_clk_parent,
+ &ccu_div_ops,
+ 0),
+ },
+};
+
+static CCU_GATE(CLK_BROM, brom_clk, "brom", ahb2_cpusys_hclk_pd, 0x100, BIT(4), 0);
+static CCU_GATE(CLK_BMU, bmu_clk, "bmu", axi4_cpusys2_aclk_pd, 0x100, BIT(5), 0);
+static CCU_GATE(CLK_AON2CPU_A2X, aon2cpu_a2x_clk, "aon2cpu-a2x", axi4_cpusys2_aclk_pd,
+ 0x134, BIT(8), 0);
+static CCU_GATE(CLK_X2X_CPUSYS, x2x_cpusys_clk, "x2x-cpusys", axi4_cpusys2_aclk_pd,
+ 0x134, BIT(7), 0);
+static CCU_GATE(CLK_CPU2AON_X2H, cpu2aon_x2h_clk, "cpu2aon-x2h", axi_aclk_pd, 0x138, BIT(8), 0);
+static CCU_GATE(CLK_CPU2PERI_X2H, cpu2peri_x2h_clk, "cpu2peri-x2h", axi4_cpusys2_aclk_pd,
+ 0x140, BIT(9), 0);
+static CCU_GATE(CLK_PERISYS_APB1_HCLK, perisys_apb1_hclk, "perisys-apb1-hclk", perisys_ahb_hclk_pd,
+ 0x150, BIT(9), 0);
+static CCU_GATE(CLK_PERISYS_APB2_HCLK, perisys_apb2_hclk, "perisys-apb2-hclk", perisys_ahb_hclk_pd,
+ 0x150, BIT(10), 0);
+static CCU_GATE(CLK_PERISYS_APB3_HCLK, perisys_apb3_hclk, "perisys-apb3-hclk", perisys_ahb_hclk_pd,
+ 0x150, BIT(11), 0);
+static CCU_GATE(CLK_PERISYS_APB4_HCLK, perisys_apb4_hclk, "perisys-apb4-hclk", perisys_ahb_hclk_pd,
+ 0x150, BIT(12), 0);
+static CCU_GATE(CLK_NPU_AXI, npu_axi_clk, "npu-axi", axi_aclk_pd, 0x1c8, BIT(5), 0);
+static CCU_GATE(CLK_CPU2VP, cpu2vp_clk, "cpu2vp", axi_aclk_pd, 0x1e0, BIT(13), 0);
+static CCU_GATE(CLK_EMMC_SDIO, emmc_sdio_clk, "emmc-sdio", video_pll_clk_pd, 0x204, BIT(30), 0);
+static CCU_GATE(CLK_GMAC1, gmac1_clk, "gmac1", gmac_pll_clk_pd, 0x204, BIT(26), 0);
+static CCU_GATE(CLK_PADCTRL1, padctrl1_clk, "padctrl1", perisys_apb_pclk_pd, 0x204, BIT(24), 0);
+static CCU_GATE(CLK_DSMART, dsmart_clk, "dsmart", perisys_apb_pclk_pd, 0x204, BIT(23), 0);
+static CCU_GATE(CLK_PADCTRL0, padctrl0_clk, "padctrl0", perisys_apb_pclk_pd, 0x204, BIT(22), 0);
+static CCU_GATE(CLK_GMAC_AXI, gmac_axi_clk, "gmac-axi", axi4_cpusys2_aclk_pd, 0x204, BIT(21), 0);
+static CCU_GATE(CLK_GPIO3, gpio3_clk, "gpio3-clk", peri2sys_apb_pclk_pd, 0x204, BIT(20), 0);
+static CCU_GATE(CLK_GMAC0, gmac0_clk, "gmac0", gmac_pll_clk_pd, 0x204, BIT(19), 0);
+static CCU_GATE(CLK_PWM, pwm_clk, "pwm", perisys_apb_pclk_pd, 0x204, BIT(18), 0);
+static CCU_GATE(CLK_QSPI0, qspi0_clk, "qspi0", video_pll_clk_pd, 0x204, BIT(17), 0);
+static CCU_GATE(CLK_QSPI1, qspi1_clk, "qspi1", video_pll_clk_pd, 0x204, BIT(16), 0);
+static CCU_GATE(CLK_SPI, spi_clk, "spi", video_pll_clk_pd, 0x204, BIT(15), 0);
+static CCU_GATE(CLK_UART0_PCLK, uart0_pclk, "uart0-pclk", perisys_apb_pclk_pd, 0x204, BIT(14), 0);
+static CCU_GATE(CLK_UART1_PCLK, uart1_pclk, "uart1-pclk", perisys_apb_pclk_pd, 0x204, BIT(13), 0);
+static CCU_GATE(CLK_UART2_PCLK, uart2_pclk, "uart2-pclk", perisys_apb_pclk_pd, 0x204, BIT(12), 0);
+static CCU_GATE(CLK_UART3_PCLK, uart3_pclk, "uart3-pclk", perisys_apb_pclk_pd, 0x204, BIT(11), 0);
+static CCU_GATE(CLK_UART4_PCLK, uart4_pclk, "uart4-pclk", perisys_apb_pclk_pd, 0x204, BIT(10), 0);
+static CCU_GATE(CLK_UART5_PCLK, uart5_pclk, "uart5-pclk", perisys_apb_pclk_pd, 0x204, BIT(9), 0);
+static CCU_GATE(CLK_GPIO0, gpio0_clk, "gpio0-clk", perisys_apb_pclk_pd, 0x204, BIT(8), 0);
+static CCU_GATE(CLK_GPIO1, gpio1_clk, "gpio1-clk", perisys_apb_pclk_pd, 0x204, BIT(7), 0);
+static CCU_GATE(CLK_GPIO2, gpio2_clk, "gpio2-clk", peri2sys_apb_pclk_pd, 0x204, BIT(6), 0);
+static CCU_GATE(CLK_I2C0, i2c0_clk, "i2c0", perisys_apb_pclk_pd, 0x204, BIT(5), 0);
+static CCU_GATE(CLK_I2C1, i2c1_clk, "i2c1", perisys_apb_pclk_pd, 0x204, BIT(4), 0);
+static CCU_GATE(CLK_I2C2, i2c2_clk, "i2c2", perisys_apb_pclk_pd, 0x204, BIT(3), 0);
+static CCU_GATE(CLK_I2C3, i2c3_clk, "i2c3", perisys_apb_pclk_pd, 0x204, BIT(2), 0);
+static CCU_GATE(CLK_I2C4, i2c4_clk, "i2c4", perisys_apb_pclk_pd, 0x204, BIT(1), 0);
+static CCU_GATE(CLK_I2C5, i2c5_clk, "i2c5", perisys_apb_pclk_pd, 0x204, BIT(0), 0);
+static CCU_GATE(CLK_SPINLOCK, spinlock_clk, "spinlock", ahb2_cpusys_hclk_pd, 0x208, BIT(10), 0);
+static CCU_GATE(CLK_DMA, dma_clk, "dma", axi4_cpusys2_aclk_pd, 0x208, BIT(8), 0);
+static CCU_GATE(CLK_MBOX0, mbox0_clk, "mbox0", apb3_cpusys_pclk_pd, 0x208, BIT(7), 0);
+static CCU_GATE(CLK_MBOX1, mbox1_clk, "mbox1", apb3_cpusys_pclk_pd, 0x208, BIT(6), 0);
+static CCU_GATE(CLK_MBOX2, mbox2_clk, "mbox2", apb3_cpusys_pclk_pd, 0x208, BIT(5), 0);
+static CCU_GATE(CLK_MBOX3, mbox3_clk, "mbox3", apb3_cpusys_pclk_pd, 0x208, BIT(4), 0);
+static CCU_GATE(CLK_WDT0, wdt0_clk, "wdt0", apb3_cpusys_pclk_pd, 0x208, BIT(3), 0);
+static CCU_GATE(CLK_WDT1, wdt1_clk, "wdt1", apb3_cpusys_pclk_pd, 0x208, BIT(2), 0);
+static CCU_GATE(CLK_TIMER0, timer0_clk, "timer0", apb3_cpusys_pclk_pd, 0x208, BIT(1), 0);
+static CCU_GATE(CLK_TIMER1, timer1_clk, "timer1", apb3_cpusys_pclk_pd, 0x208, BIT(0), 0);
+static CCU_GATE(CLK_SRAM0, sram0_clk, "sram0", axi_aclk_pd, 0x20c, BIT(4), 0);
+static CCU_GATE(CLK_SRAM1, sram1_clk, "sram1", axi_aclk_pd, 0x20c, BIT(3), 0);
+static CCU_GATE(CLK_SRAM2, sram2_clk, "sram2", axi_aclk_pd, 0x20c, BIT(2), 0);
+static CCU_GATE(CLK_SRAM3, sram3_clk, "sram3", axi_aclk_pd, 0x20c, BIT(1), 0);
+
+static CLK_FIXED_FACTOR_HW(gmac_pll_clk_100m, "gmac-pll-clk-100m",
+ &gmac_pll_clk.common.hw, 10, 1, 0);
+
+static const struct clk_parent_data uart_sclk_parents[] = {
+ { .hw = &gmac_pll_clk_100m.hw },
+ { .index = 0 },
+};
+
+struct ccu_mux uart_sclk = {
+ .mux = TH_CCU_ARG(0, 1),
+ .common = {
+ .clkid = CLK_UART_SCLK,
+ .cfg0 = 0x210,
+ .hw.init = CLK_HW_INIT_PARENTS_DATA("uart-sclk",
+ uart_sclk_parents,
+ &clk_mux_ops,
+ 0),
+ }
+};
+
+static struct ccu_common *th1520_pll_clks[] = {
+ &cpu_pll0_clk.common,
+ &cpu_pll1_clk.common,
+ &gmac_pll_clk.common,
+ &video_pll_clk.common,
+ &dpu0_pll_clk.common,
+ &dpu1_pll_clk.common,
+ &tee_pll_clk.common,
+};
+
+static struct ccu_common *th1520_div_clks[] = {
+ &ahb2_cpusys_hclk.common,
+ &apb3_cpusys_pclk.common,
+ &axi4_cpusys2_aclk.common,
+ &perisys_ahb_hclk.common,
+ &perisys_apb_pclk.common,
+ &axi_aclk.common,
+ &peri2sys_apb_pclk.common,
+ &out1_clk.common,
+ &out2_clk.common,
+ &out3_clk.common,
+ &out4_clk.common,
+ &apb_pclk.common,
+ &npu_clk.common,
+ &vi_clk.common,
+ &vi_ahb_clk.common,
+ &vo_axi_clk.common,
+ &vp_apb_clk.common,
+ &vp_axi_clk.common,
+ &cpu2vp_clk.common,
+ &venc_clk.common,
+ &dpu0_clk.common,
+ &dpu1_clk.common,
+};
+
+static struct ccu_common *th1520_mux_clks[] = {
+ &c910_i0_clk.common,
+ &c910_clk.common,
+ &uart_sclk.common,
+};
+
+static struct ccu_common *th1520_gate_clks[] = {
+ &emmc_sdio_clk.common,
+ &aon2cpu_a2x_clk.common,
+ &x2x_cpusys_clk.common,
+ &brom_clk.common,
+ &bmu_clk.common,
+ &cpu2aon_x2h_clk.common,
+ &cpu2peri_x2h_clk.common,
+ &perisys_apb1_hclk.common,
+ &perisys_apb2_hclk.common,
+ &perisys_apb3_hclk.common,
+ &perisys_apb4_hclk.common,
+ &npu_axi_clk.common,
+ &gmac1_clk.common,
+ &padctrl1_clk.common,
+ &dsmart_clk.common,
+ &padctrl0_clk.common,
+ &gmac_axi_clk.common,
+ &gpio3_clk.common,
+ &gmac0_clk.common,
+ &pwm_clk.common,
+ &qspi0_clk.common,
+ &qspi1_clk.common,
+ &spi_clk.common,
+ &uart0_pclk.common,
+ &uart1_pclk.common,
+ &uart2_pclk.common,
+ &uart3_pclk.common,
+ &uart4_pclk.common,
+ &uart5_pclk.common,
+ &gpio0_clk.common,
+ &gpio1_clk.common,
+ &gpio2_clk.common,
+ &i2c0_clk.common,
+ &i2c1_clk.common,
+ &i2c2_clk.common,
+ &i2c3_clk.common,
+ &i2c4_clk.common,
+ &i2c5_clk.common,
+ &spinlock_clk.common,
+ &dma_clk.common,
+ &mbox0_clk.common,
+ &mbox1_clk.common,
+ &mbox2_clk.common,
+ &mbox3_clk.common,
+ &wdt0_clk.common,
+ &wdt1_clk.common,
+ &timer0_clk.common,
+ &timer1_clk.common,
+ &sram0_clk.common,
+ &sram1_clk.common,
+ &sram2_clk.common,
+ &sram3_clk.common,
+};
+
+#define NR_CLKS (CLK_UART_SCLK + 1)
+
+static const struct regmap_config th1520_clk_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .fast_io = true,
+};
+
+static int th1520_clk_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct clk_hw_onecell_data *priv;
+
+ struct regmap *map;
+ void __iomem *base;
+ struct clk_hw *hw;
+ int ret, i;
+
+ priv = devm_kzalloc(dev, struct_size(priv, hws, NR_CLKS), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->num = NR_CLKS;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ map = devm_regmap_init_mmio(dev, base, &th1520_clk_regmap_config);
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+
+ for (i = 0; i < ARRAY_SIZE(th1520_pll_clks); i++) {
+ struct ccu_pll *cp = hw_to_ccu_pll(&th1520_pll_clks[i]->hw);
+
+ th1520_pll_clks[i]->map = map;
+
+ ret = devm_clk_hw_register(dev, &th1520_pll_clks[i]->hw);
+ if (ret)
+ return ret;
+
+ priv->hws[cp->common.clkid] = &cp->common.hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(th1520_div_clks); i++) {
+ struct ccu_div *cd = hw_to_ccu_div(&th1520_div_clks[i]->hw);
+
+ th1520_div_clks[i]->map = map;
+
+ ret = devm_clk_hw_register(dev, &th1520_div_clks[i]->hw);
+ if (ret)
+ return ret;
+
+ priv->hws[cd->common.clkid] = &cd->common.hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(th1520_mux_clks); i++) {
+ struct ccu_mux *cm = hw_to_ccu_mux(&th1520_mux_clks[i]->hw);
+ const struct clk_init_data *init = cm->common.hw.init;
+
+ th1520_mux_clks[i]->map = map;
+ hw = devm_clk_hw_register_mux_parent_data_table(dev,
+ init->name,
+ init->parent_data,
+ init->num_parents,
+ 0,
+ base + cm->common.cfg0,
+ cm->mux.shift,
+ cm->mux.width,
+ 0, NULL, NULL);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ priv->hws[cm->common.clkid] = hw;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(th1520_gate_clks); i++) {
+ struct ccu_gate *cg = hw_to_ccu_gate(&th1520_gate_clks[i]->hw);
+
+ th1520_gate_clks[i]->map = map;
+
+ hw = devm_clk_hw_register_gate_parent_data(dev,
+ cg->common.hw.init->name,
+ cg->common.hw.init->parent_data,
+ 0, base + cg->common.cfg0,
+ ffs(cg->enable) - 1, 0, NULL);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ priv->hws[cg->common.clkid] = hw;
+ }
+
+ ret = devm_clk_hw_register(dev, &osc12m_clk.hw);
+ if (ret)
+ return ret;
+ priv->hws[CLK_OSC12M] = &osc12m_clk.hw;
+
+ ret = devm_clk_hw_register(dev, &gmac_pll_clk_100m.hw);
+ if (ret)
+ return ret;
+ priv->hws[CLK_PLL_GMAC_100M] = &gmac_pll_clk_100m.hw;
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct of_device_id th1520_clk_match[] = {
+ {
+ .compatible = "thead,th1520-clk-ap",
+ },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, th1520_clk_match);
+
+static struct platform_driver th1520_clk_driver = {
+ .probe = th1520_clk_probe,
+ .driver = {
+ .name = "th1520-clk",
+ .of_match_table = th1520_clk_match,
+ },
+};
+module_platform_driver(th1520_clk_driver);
+
+MODULE_DESCRIPTION("T-HEAD TH1520 AP Clock driver");
+MODULE_AUTHOR("Yangtao Li <frank.li@vivo.com>");
+MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 3/7] riscv: dts: thead: Add TH1520 AP_SUBSYS clock controller
2024-06-24 2:12 [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller Drew Fustini
2024-06-24 2:12 ` [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller Drew Fustini
2024-06-24 2:12 ` [PATCH v2 2/7] clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks Drew Fustini
@ 2024-06-24 2:12 ` Drew Fustini
2024-06-24 2:12 ` [PATCH v2 4/7] riscv: dts: thead: change TH1520 uart nodes to use " Drew Fustini
` (3 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Drew Fustini @ 2024-06-24 2:12 UTC (permalink / raw)
To: Jisheng Zhang, Guo Ren, Fu Wei, Yangtao Li, Thomas Bonnefille,
Emil Renner Berthing, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini
Add node for the AP_SUBSYS clock controller on the T-Head TH1520 SoC.
Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
---
arch/riscv/boot/dts/thead/th1520.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index d2fa25839012..10a38ed55658 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -5,6 +5,7 @@
*/
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/clock/thead,th1520-clk-ap.h>
/ {
compatible = "thead,th1520";
@@ -161,6 +162,13 @@ soc {
dma-noncoherent;
ranges;
+ clk: clock-controller@ffef010000 {
+ compatible = "thead,th1520-clk-ap";
+ reg = <0xff 0xef010000 0x0 0x1000>;
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
+
plic: interrupt-controller@ffd8000000 {
compatible = "thead,th1520-plic", "thead,c900-plic";
reg = <0xff 0xd8000000 0x0 0x01000000>;
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 4/7] riscv: dts: thead: change TH1520 uart nodes to use clock controller
2024-06-24 2:12 [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller Drew Fustini
` (2 preceding siblings ...)
2024-06-24 2:12 ` [PATCH v2 3/7] riscv: dts: thead: Add TH1520 AP_SUBSYS clock controller Drew Fustini
@ 2024-06-24 2:12 ` Drew Fustini
2024-06-24 2:12 ` [PATCH v2 5/7] riscv: dts: thead: change TH1520 mmc " Drew Fustini
` (2 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Drew Fustini @ 2024-06-24 2:12 UTC (permalink / raw)
To: Jisheng Zhang, Guo Ren, Fu Wei, Yangtao Li, Thomas Bonnefille,
Emil Renner Berthing, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini
Change the clock property in TH1520 uart nodes to a clock provided by
AP_SUBSYS clock controller.
Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
---
arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts | 4 ----
.../boot/dts/thead/th1520-lichee-module-4a.dtsi | 4 ----
arch/riscv/boot/dts/thead/th1520.dtsi | 24 +++++++++++-----------
3 files changed, 12 insertions(+), 20 deletions(-)
diff --git a/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts b/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
index d9b4de9e4757..164afd18b56c 100644
--- a/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
+++ b/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
@@ -52,10 +52,6 @@ &sdhci_clk {
clock-frequency = <198000000>;
};
-&uart_sclk {
- clock-frequency = <100000000>;
-};
-
&dmac0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi b/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
index 1365d3a512a3..1b7ede570994 100644
--- a/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
@@ -33,10 +33,6 @@ &sdhci_clk {
clock-frequency = <198000000>;
};
-&uart_sclk {
- clock-frequency = <100000000>;
-};
-
&dmac0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index 10a38ed55658..66df04ceb3e4 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -141,12 +141,6 @@ apb_clk: apb-clk-clock {
#clock-cells = <0>;
};
- uart_sclk: uart-sclk-clock {
- compatible = "fixed-clock";
- clock-output-names = "uart_sclk";
- #clock-cells = <0>;
- };
-
sdhci_clk: sdhci-clock {
compatible = "fixed-clock";
clock-frequency = <198000000>;
@@ -195,7 +189,8 @@ uart0: serial@ffe7014000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xe7014000 0x0 0x100>;
interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART0_PCLK>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -232,7 +227,8 @@ uart1: serial@ffe7f00000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xe7f00000 0x0 0x100>;
interrupts = <37 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART1_PCLK>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -242,7 +238,8 @@ uart3: serial@ffe7f04000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xe7f04000 0x0 0x100>;
interrupts = <39 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART3_PCLK>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -324,7 +321,8 @@ uart2: serial@ffec010000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xec010000 0x0 0x4000>;
interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART2_PCLK>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -386,7 +384,8 @@ uart4: serial@fff7f08000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xf7f08000 0x0 0x4000>;
interrupts = <40 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART4_PCLK>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
@@ -396,7 +395,8 @@ uart5: serial@fff7f0c000 {
compatible = "snps,dw-apb-uart";
reg = <0xff 0xf7f0c000 0x0 0x4000>;
interrupts = <41 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&uart_sclk>;
+ clocks = <&clk CLK_UART_SCLK>, <&clk CLK_UART5_PCLK>;
+ clock-names = "baudclk", "apb_pclk";
reg-shift = <2>;
reg-io-width = <4>;
status = "disabled";
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 5/7] riscv: dts: thead: change TH1520 mmc nodes to use clock controller
2024-06-24 2:12 [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller Drew Fustini
` (3 preceding siblings ...)
2024-06-24 2:12 ` [PATCH v2 4/7] riscv: dts: thead: change TH1520 uart nodes to use " Drew Fustini
@ 2024-06-24 2:12 ` Drew Fustini
2024-06-24 2:12 ` [PATCH v2 6/7] riscv: dts: thead: update TH1520 dma and timer " Drew Fustini
2024-06-24 2:12 ` [PATCH v2 7/7] riscv: dts: thead: add clock to TH1520 gpio nodes Drew Fustini
6 siblings, 0 replies; 15+ messages in thread
From: Drew Fustini @ 2024-06-24 2:12 UTC (permalink / raw)
To: Jisheng Zhang, Guo Ren, Fu Wei, Yangtao Li, Thomas Bonnefille,
Emil Renner Berthing, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini
Change the clock property in the TH1520 mmc controller nodes to a clock
provided by AP_SYS clock controller.
Remove sdhci fixed clock reference from BeagleV Ahead and LPI4a dts.
Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
---
arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts | 4 ----
arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi | 4 ----
arch/riscv/boot/dts/thead/th1520.dtsi | 13 +++----------
3 files changed, 3 insertions(+), 18 deletions(-)
diff --git a/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts b/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
index 164afd18b56c..55f1ed0cb433 100644
--- a/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
+++ b/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
@@ -48,10 +48,6 @@ &apb_clk {
clock-frequency = <62500000>;
};
-&sdhci_clk {
- clock-frequency = <198000000>;
-};
-
&dmac0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi b/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
index 1b7ede570994..762eceb415f8 100644
--- a/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
@@ -29,10 +29,6 @@ &apb_clk {
clock-frequency = <62500000>;
};
-&sdhci_clk {
- clock-frequency = <198000000>;
-};
-
&dmac0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index 66df04ceb3e4..ce3a0847aa9c 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -141,13 +141,6 @@ apb_clk: apb-clk-clock {
#clock-cells = <0>;
};
- sdhci_clk: sdhci-clock {
- compatible = "fixed-clock";
- clock-frequency = <198000000>;
- clock-output-names = "sdhci_clk";
- #clock-cells = <0>;
- };
-
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
@@ -200,7 +193,7 @@ emmc: mmc@ffe7080000 {
compatible = "thead,th1520-dwcmshc";
reg = <0xff 0xe7080000 0x0 0x10000>;
interrupts = <62 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
+ clocks = <&clk CLK_EMMC_SDIO>;
clock-names = "core";
status = "disabled";
};
@@ -209,7 +202,7 @@ sdio0: mmc@ffe7090000 {
compatible = "thead,th1520-dwcmshc";
reg = <0xff 0xe7090000 0x0 0x10000>;
interrupts = <64 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
+ clocks = <&clk CLK_EMMC_SDIO>;
clock-names = "core";
status = "disabled";
};
@@ -218,7 +211,7 @@ sdio1: mmc@ffe70a0000 {
compatible = "thead,th1520-dwcmshc";
reg = <0xff 0xe70a0000 0x0 0x10000>;
interrupts = <71 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&sdhci_clk>;
+ clocks = <&clk CLK_EMMC_SDIO>;
clock-names = "core";
status = "disabled";
};
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 6/7] riscv: dts: thead: update TH1520 dma and timer nodes to use clock controller
2024-06-24 2:12 [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller Drew Fustini
` (4 preceding siblings ...)
2024-06-24 2:12 ` [PATCH v2 5/7] riscv: dts: thead: change TH1520 mmc " Drew Fustini
@ 2024-06-24 2:12 ` Drew Fustini
2024-06-24 2:12 ` [PATCH v2 7/7] riscv: dts: thead: add clock to TH1520 gpio nodes Drew Fustini
6 siblings, 0 replies; 15+ messages in thread
From: Drew Fustini @ 2024-06-24 2:12 UTC (permalink / raw)
To: Jisheng Zhang, Guo Ren, Fu Wei, Yangtao Li, Thomas Bonnefille,
Emil Renner Berthing, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini
Change the dma-controller and timer nodes to use the APB clock provided
by the AP_SUBSYS clock controller.
Remove apb_clk reference from BeagleV Ahead and LPI4a dts.
Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
---
arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts | 4 ----
.../boot/dts/thead/th1520-lichee-module-4a.dtsi | 4 ----
arch/riscv/boot/dts/thead/th1520.dtsi | 24 ++++++++--------------
3 files changed, 9 insertions(+), 23 deletions(-)
diff --git a/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts b/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
index 55f1ed0cb433..1180e41c7b07 100644
--- a/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
+++ b/arch/riscv/boot/dts/thead/th1520-beaglev-ahead.dts
@@ -44,10 +44,6 @@ &osc_32k {
clock-frequency = <32768>;
};
-&apb_clk {
- clock-frequency = <62500000>;
-};
-
&dmac0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi b/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
index 762eceb415f8..78977bdbbe3d 100644
--- a/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520-lichee-module-4a.dtsi
@@ -25,10 +25,6 @@ &osc_32k {
clock-frequency = <32768>;
};
-&apb_clk {
- clock-frequency = <62500000>;
-};
-
&dmac0 {
status = "okay";
};
diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index ce3a0847aa9c..d05002ad7c96 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -135,12 +135,6 @@ osc_32k: 32k-oscillator {
#clock-cells = <0>;
};
- apb_clk: apb-clk-clock {
- compatible = "fixed-clock";
- clock-output-names = "apb_clk";
- #clock-cells = <0>;
- };
-
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
@@ -325,7 +319,7 @@ dmac0: dma-controller@ffefc00000 {
compatible = "snps,axi-dma-1.01a";
reg = <0xff 0xefc00000 0x0 0x1000>;
interrupts = <27 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&apb_clk>, <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>, <&clk CLK_PERI_APB_PCLK>;
clock-names = "core-clk", "cfgr-clk";
#dma-cells = <1>;
dma-channels = <4>;
@@ -340,7 +334,7 @@ dmac0: dma-controller@ffefc00000 {
timer0: timer@ffefc32000 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc32000 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <16 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -349,7 +343,7 @@ timer0: timer@ffefc32000 {
timer1: timer@ffefc32014 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc32014 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -358,7 +352,7 @@ timer1: timer@ffefc32014 {
timer2: timer@ffefc32028 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc32028 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <18 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -367,7 +361,7 @@ timer2: timer@ffefc32028 {
timer3: timer@ffefc3203c {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xefc3203c 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -398,7 +392,7 @@ uart5: serial@fff7f0c000 {
timer4: timer@ffffc33000 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xffc33000 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -407,7 +401,7 @@ timer4: timer@ffffc33000 {
timer5: timer@ffffc33014 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xffc33014 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <21 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -416,7 +410,7 @@ timer5: timer@ffffc33014 {
timer6: timer@ffffc33028 {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xffc33028 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
@@ -425,7 +419,7 @@ timer6: timer@ffffc33028 {
timer7: timer@ffffc3303c {
compatible = "snps,dw-apb-timer";
reg = <0xff 0xffc3303c 0x0 0x14>;
- clocks = <&apb_clk>;
+ clocks = <&clk CLK_PERI_APB_PCLK>;
clock-names = "timer";
interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 7/7] riscv: dts: thead: add clock to TH1520 gpio nodes
2024-06-24 2:12 [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller Drew Fustini
` (5 preceding siblings ...)
2024-06-24 2:12 ` [PATCH v2 6/7] riscv: dts: thead: update TH1520 dma and timer " Drew Fustini
@ 2024-06-24 2:12 ` Drew Fustini
6 siblings, 0 replies; 15+ messages in thread
From: Drew Fustini @ 2024-06-24 2:12 UTC (permalink / raw)
To: Jisheng Zhang, Guo Ren, Fu Wei, Yangtao Li, Thomas Bonnefille,
Emil Renner Berthing, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Paul Walmsley,
Palmer Dabbelt, Albert Ou
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini
Add clock property to TH1520 gpio controller nodes. These clock gates
refer to corresponding enable bits in the peripheral clock gate control
register. Refer to register PERI_CLK_CFG in section 4.4.2.2.52 of the
TH1520 System User Manual.
Link: https://git.beagleboard.org/beaglev-ahead/beaglev-ahead/-/tree/main/docs
Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
---
arch/riscv/boot/dts/thead/th1520.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/riscv/boot/dts/thead/th1520.dtsi b/arch/riscv/boot/dts/thead/th1520.dtsi
index d05002ad7c96..351e09beab70 100644
--- a/arch/riscv/boot/dts/thead/th1520.dtsi
+++ b/arch/riscv/boot/dts/thead/th1520.dtsi
@@ -237,6 +237,7 @@ gpio2: gpio@ffe7f34000 {
reg = <0xff 0xe7f34000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clk CLK_GPIO2>;
portc: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
@@ -255,6 +256,7 @@ gpio3: gpio@ffe7f38000 {
reg = <0xff 0xe7f38000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clk CLK_GPIO3>;
portd: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
@@ -273,6 +275,7 @@ gpio0: gpio@ffec005000 {
reg = <0xff 0xec005000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clk CLK_GPIO0>;
porta: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
@@ -291,6 +294,7 @@ gpio1: gpio@ffec006000 {
reg = <0xff 0xec006000 0x0 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
+ clocks = <&clk CLK_GPIO1>;
portb: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/7] clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks
2024-06-24 2:12 ` [PATCH v2 2/7] clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks Drew Fustini
@ 2024-07-10 23:17 ` Stephen Boyd
2024-07-11 6:55 ` Drew Fustini
0 siblings, 1 reply; 15+ messages in thread
From: Stephen Boyd @ 2024-07-10 23:17 UTC (permalink / raw)
To: Albert Ou, Conor Dooley, Drew Fustini, Emil Renner Berthing,
Fu Wei, Guo Ren, Jisheng Zhang, Krzysztof Kozlowski,
Michael Turquette, Palmer Dabbelt, Paul Walmsley, Rob Herring,
Thomas Bonnefille, Yangtao Li
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini
Quoting Drew Fustini (2024-06-23 19:12:32)
> diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c
> new file mode 100644
> index 000000000000..982d4d40f783
> --- /dev/null
> +++ b/drivers/clk/thead/clk-th1520-ap.c
> @@ -0,0 +1,1086 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
> + * Copyright (C) 2023 Vivo Communication Technology Co. Ltd.
> + * Authors: Yangtao Li <frank.li@vivo.com>
> + */
> +
> +#include <dt-bindings/clock/thead,th1520-clk-ap.h>
Preferably include dt-bindings after linux includes.
> +#include <linux/bitfield.h>
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#define TH1520_PLL_POSTDIV2 GENMASK(26, 24)
> +#define TH1520_PLL_POSTDIV1 GENMASK(22, 20)
> +#define TH1520_PLL_FBDIV GENMASK(19, 8)
> +#define TH1520_PLL_REFDIV GENMASK(5, 0)
> +#define TH1520_PLL_BYPASS BIT(30)
> +#define TH1520_PLL_DSMPD BIT(24)
> +#define TH1520_PLL_FRAC GENMASK(23, 0)
> +#define TH1520_PLL_FRAC_BITS 24
[...]
> +
> +static unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct ccu_pll *pll = hw_to_ccu_pll(hw);
> + unsigned long div, mul, frac, rate = parent_rate;
> + unsigned int cfg0, cfg1;
> +
> + regmap_read(pll->common.map, pll->common.cfg0, &cfg0);
> + regmap_read(pll->common.map, pll->common.cfg1, &cfg1);
> +
> + mul = FIELD_GET(TH1520_PLL_FBDIV, cfg0);
> + div = FIELD_GET(TH1520_PLL_REFDIV, cfg0);
> + if (!(cfg1 & TH1520_PLL_DSMPD)) {
> + mul <<= TH1520_PLL_FRAC_BITS;
> + frac = FIELD_GET(TH1520_PLL_FRAC, cfg1);
> + mul += frac;
> + div <<= TH1520_PLL_FRAC_BITS;
> + }
> + rate = parent_rate * mul;
> + do_div(rate, div);
'rate' is only unsigned long, so do_div() isn't needed here. Perhaps if
'parent_rate * mul' can overflow 32-bits then 'rate' should be
u64.
> + return rate;
> +}
> +
> +static unsigned long th1520_pll_postdiv_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct ccu_pll *pll = hw_to_ccu_pll(hw);
> + unsigned long rate = parent_rate;
> + unsigned int cfg0, cfg1;
> +
> + regmap_read(pll->common.map, pll->common.cfg0, &cfg0);
> + regmap_read(pll->common.map, pll->common.cfg1, &cfg1);
> +
> + if (cfg1 & TH1520_PLL_BYPASS)
> + return rate;
> +
> + do_div(rate, FIELD_GET(TH1520_PLL_POSTDIV1, cfg0) *
Same, 'rate' is unsigned long. Did you get some compilation error
without this? How big is the divisor going to be? The fields are only
3-bits wide, so the multiplication would fit into a u32 just fine. Given
that 'rate' is unsigned long though I think you can just put the
multiplication result into a local variable that's also unsigned long
and then just write the divide with unsigned longs
div = FIELD_GET(...) * FIELD_GET(...);
return rate / div;
> + FIELD_GET(TH1520_PLL_POSTDIV2, cfg0));
> +
> + return rate;
> +}
> +
> +static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + unsigned long rate = parent_rate;
> +
> + rate = th1520_pll_vco_recalc_rate(hw, rate);
> + rate = th1520_pll_postdiv_recalc_rate(hw, rate);
> +
> + return rate;
> +}
Please fold this in
----8<---
diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c
index 982d4d40f783..0c3821d50765 100644
--- a/drivers/clk/thead/clk-th1520-ap.c
+++ b/drivers/clk/thead/clk-th1520-ap.c
@@ -411,7 +411,7 @@ static const struct clk_parent_data c910_i0_parents[] = {
{ .index = 0 }
};
-struct ccu_mux c910_i0_clk = {
+static struct ccu_mux c910_i0_clk = {
.mux = TH_CCU_ARG(1, 1),
.common = {
.clkid = CLK_C910_I0,
@@ -428,7 +428,7 @@ static const struct clk_parent_data c910_parents[] = {
{ .hw = &cpu_pll1_clk.common.hw }
};
-struct ccu_mux c910_clk = {
+static struct ccu_mux c910_clk = {
.mux = TH_CCU_ARG(0, 1),
.common = {
.clkid = CLK_C910,
@@ -845,7 +845,7 @@ static const struct clk_parent_data uart_sclk_parents[] = {
{ .index = 0 },
};
-struct ccu_mux uart_sclk = {
+static struct ccu_mux uart_sclk = {
.mux = TH_CCU_ARG(0, 1),
.common = {
.clkid = CLK_UART_SCLK,
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller
2024-06-24 2:12 ` [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller Drew Fustini
@ 2024-07-10 23:17 ` Stephen Boyd
2024-07-26 8:45 ` Emil Renner Berthing
0 siblings, 1 reply; 15+ messages in thread
From: Stephen Boyd @ 2024-07-10 23:17 UTC (permalink / raw)
To: Albert Ou, Conor Dooley, Drew Fustini, Emil Renner Berthing,
Fu Wei, Guo Ren, Jisheng Zhang, Krzysztof Kozlowski,
Michael Turquette, Palmer Dabbelt, Paul Walmsley, Rob Herring,
Thomas Bonnefille, Yangtao Li
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Drew Fustini,
Conor Dooley
Quoting Drew Fustini (2024-06-23 19:12:31)
> Document bindings for the T-Head TH1520 AP sub-system clock controller.
>
> Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
> Co-developed-by: Yangtao Li <frank.li@vivo.com>
> Signed-off-by: Yangtao Li <frank.li@vivo.com>
> Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
> Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
> ---
Applied to clk-next
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 2/7] clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks
2024-07-10 23:17 ` Stephen Boyd
@ 2024-07-11 6:55 ` Drew Fustini
0 siblings, 0 replies; 15+ messages in thread
From: Drew Fustini @ 2024-07-11 6:55 UTC (permalink / raw)
To: Stephen Boyd
Cc: Albert Ou, Conor Dooley, Emil Renner Berthing, Fu Wei, Guo Ren,
Jisheng Zhang, Krzysztof Kozlowski, Michael Turquette,
Palmer Dabbelt, Paul Walmsley, Rob Herring, Thomas Bonnefille,
Yangtao Li, linux-riscv, linux-clk, devicetree, linux-kernel
On Wed, Jul 10, 2024 at 04:17:12PM -0700, Stephen Boyd wrote:
> Quoting Drew Fustini (2024-06-23 19:12:32)
> > diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c
> > new file mode 100644
> > index 000000000000..982d4d40f783
> > --- /dev/null
> > +++ b/drivers/clk/thead/clk-th1520-ap.c
> > @@ -0,0 +1,1086 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org>
> > + * Copyright (C) 2023 Vivo Communication Technology Co. Ltd.
> > + * Authors: Yangtao Li <frank.li@vivo.com>
> > + */
> > +
> > +#include <dt-bindings/clock/thead,th1520-clk-ap.h>
>
> Preferably include dt-bindings after linux includes.
Okay, I will move it.
>
> > +#include <linux/bitfield.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/device.h>
> > +#include <linux/module.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +
> > +#define TH1520_PLL_POSTDIV2 GENMASK(26, 24)
> > +#define TH1520_PLL_POSTDIV1 GENMASK(22, 20)
> > +#define TH1520_PLL_FBDIV GENMASK(19, 8)
> > +#define TH1520_PLL_REFDIV GENMASK(5, 0)
> > +#define TH1520_PLL_BYPASS BIT(30)
> > +#define TH1520_PLL_DSMPD BIT(24)
> > +#define TH1520_PLL_FRAC GENMASK(23, 0)
> > +#define TH1520_PLL_FRAC_BITS 24
> [...]
> > +
> > +static unsigned long th1520_pll_vco_recalc_rate(struct clk_hw *hw,
> > + unsigned long parent_rate)
> > +{
> > + struct ccu_pll *pll = hw_to_ccu_pll(hw);
> > + unsigned long div, mul, frac, rate = parent_rate;
> > + unsigned int cfg0, cfg1;
> > +
> > + regmap_read(pll->common.map, pll->common.cfg0, &cfg0);
> > + regmap_read(pll->common.map, pll->common.cfg1, &cfg1);
> > +
> > + mul = FIELD_GET(TH1520_PLL_FBDIV, cfg0);
> > + div = FIELD_GET(TH1520_PLL_REFDIV, cfg0);
> > + if (!(cfg1 & TH1520_PLL_DSMPD)) {
> > + mul <<= TH1520_PLL_FRAC_BITS;
> > + frac = FIELD_GET(TH1520_PLL_FRAC, cfg1);
> > + mul += frac;
> > + div <<= TH1520_PLL_FRAC_BITS;
> > + }
> > + rate = parent_rate * mul;
> > + do_div(rate, div);
>
> 'rate' is only unsigned long, so do_div() isn't needed here. Perhaps if
> 'parent_rate * mul' can overflow 32-bits then 'rate' should be
> u64.
Thanks for pointing that out. I will make 'rate' u64 as I believe
'parent_rate * mul' could overflow:
The ref clock for all the PLLs on this SoC is intended to be 24 MHz
(section 4.3.2 PLL Resources [1]). Thus it is expected that parent_rate
will use 24 bits.
'mul' is set to TH1520_PLL_FBDIV which is 12 bits. In DSMPD mode, 'mul'
gets shifted left by TH1520_PLL_FRAC_BITS which is 24 bits.
> > + return rate;
> > +}
> > +
> > +static unsigned long th1520_pll_postdiv_recalc_rate(struct clk_hw *hw,
> > + unsigned long parent_rate)
> > +{
> > + struct ccu_pll *pll = hw_to_ccu_pll(hw);
> > + unsigned long rate = parent_rate;
> > + unsigned int cfg0, cfg1;
> > +
> > + regmap_read(pll->common.map, pll->common.cfg0, &cfg0);
> > + regmap_read(pll->common.map, pll->common.cfg1, &cfg1);
> > +
> > + if (cfg1 & TH1520_PLL_BYPASS)
> > + return rate;
> > +
> > + do_div(rate, FIELD_GET(TH1520_PLL_POSTDIV1, cfg0) *
>
> Same, 'rate' is unsigned long. Did you get some compilation error
> without this? How big is the divisor going to be? The fields are only
> 3-bits wide, so the multiplication would fit into a u32 just fine. Given
> that 'rate' is unsigned long though I think you can just put the
> multiplication result into a local variable that's also unsigned long
> and then just write the divide with unsigned longs
>
> div = FIELD_GET(...) * FIELD_GET(...);
>
> return rate / div;
I didn't get any compiler errors. I had copied do_div() from another
driver that I was looking at.
You are right that TH1520_PLL_POSTDIV1 and TH1520_PLL_POSTDIV2 are both
just 3 bits each. Thus I think the maximum divisor is 64. I'll change
to the simpler "rate / div" that you suggest.
> > + FIELD_GET(TH1520_PLL_POSTDIV2, cfg0));
> > +
> > + return rate;
> > +}
> > +
> > +static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
> > + unsigned long parent_rate)
> > +{
> > + unsigned long rate = parent_rate;
> > +
> > + rate = th1520_pll_vco_recalc_rate(hw, rate);
> > + rate = th1520_pll_postdiv_recalc_rate(hw, rate);
> > +
> > + return rate;
> > +}
>
> Please fold this in
Will do.
Thanks for the review,
Drew
[1] https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller
2024-07-10 23:17 ` Stephen Boyd
@ 2024-07-26 8:45 ` Emil Renner Berthing
2024-07-26 16:38 ` Drew Fustini
0 siblings, 1 reply; 15+ messages in thread
From: Emil Renner Berthing @ 2024-07-26 8:45 UTC (permalink / raw)
To: Stephen Boyd, Albert Ou, Conor Dooley, Drew Fustini,
Emil Renner Berthing, Fu Wei, Guo Ren, Jisheng Zhang,
Krzysztof Kozlowski, Michael Turquette, Palmer Dabbelt,
Paul Walmsley, Rob Herring, Thomas Bonnefille, Yangtao Li
Cc: linux-riscv, linux-clk, devicetree, linux-kernel, Conor Dooley
Stephen Boyd wrote:
> Quoting Drew Fustini (2024-06-23 19:12:31)
> > Document bindings for the T-Head TH1520 AP sub-system clock controller.
> >
> > Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
> > Co-developed-by: Yangtao Li <frank.li@vivo.com>
> > Signed-off-by: Yangtao Li <frank.li@vivo.com>
> > Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
> > Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
> > ---
>
> Applied to clk-next
Thanks, but this driver seems a bit incomplete. With this applied the Lichee Pi
4A no longer boots without the clk_ignore_unused kernel parameter.
/Emil
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller
2024-07-26 8:45 ` Emil Renner Berthing
@ 2024-07-26 16:38 ` Drew Fustini
2024-07-27 5:21 ` Icenowy Zheng
0 siblings, 1 reply; 15+ messages in thread
From: Drew Fustini @ 2024-07-26 16:38 UTC (permalink / raw)
To: Emil Renner Berthing
Cc: Stephen Boyd, Albert Ou, Conor Dooley, Drew Fustini, Fu Wei,
Guo Ren, Jisheng Zhang, Krzysztof Kozlowski, Michael Turquette,
Palmer Dabbelt, Paul Walmsley, Rob Herring, Thomas Bonnefille,
Yangtao Li, linux-riscv, linux-clk, devicetree, linux-kernel,
Conor Dooley
On Fri, Jul 26, 2024 at 03:45:36AM -0500, Emil Renner Berthing wrote:
> Stephen Boyd wrote:
> > Quoting Drew Fustini (2024-06-23 19:12:31)
> > > Document bindings for the T-Head TH1520 AP sub-system clock controller.
> > >
> > > Link: https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
> > > Co-developed-by: Yangtao Li <frank.li@vivo.com>
> > > Signed-off-by: Yangtao Li <frank.li@vivo.com>
> > > Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
> > > Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
> > > ---
> >
> > Applied to clk-next
>
> Thanks, but this driver seems a bit incomplete. With this applied the Lichee Pi
> 4A no longer boots without the clk_ignore_unused kernel parameter.
>
> /Emil
Is this the case when you apply the dts patches from this series?
The dts patches won't go in until 6.12 so I don't think the presence of
the clk-th1520-ap.c itself in 6.11 would break existing systems.
That said, I have been using clk_ignore_unused. I had been thinking that
made sense because the full set of clock controller drivers like
AON_SUBSYS (always on), AUDIO_SUBSYS, DSP_SUBSYS, etc, are not present
yet in mainline. However, the T-Head vendor kernel does have drivers for
all those clock controllers and I was suprised to see that the vendor
kernel fails to boot when I just tested removing clk_ignore_unused.
As for clk-th1520-ap.c in mainline, I'll investigate further which clk
disables seem to causing the boot failure when using the dts from this
series. I suspect I may need to add nodes that will cause the necessary
clks to be enabled by their respective drivers.
Thanks,
Drew
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller
2024-07-26 16:38 ` Drew Fustini
@ 2024-07-27 5:21 ` Icenowy Zheng
2024-07-30 23:05 ` Drew Fustini
0 siblings, 1 reply; 15+ messages in thread
From: Icenowy Zheng @ 2024-07-27 5:21 UTC (permalink / raw)
To: Drew Fustini, Emil Renner Berthing
Cc: Stephen Boyd, Albert Ou, Conor Dooley, Drew Fustini, Fu Wei,
Guo Ren, Jisheng Zhang, Krzysztof Kozlowski, Michael Turquette,
Palmer Dabbelt, Paul Walmsley, Rob Herring, Thomas Bonnefille,
Yangtao Li, linux-riscv, linux-clk, devicetree, linux-kernel,
Conor Dooley
在 2024-07-26星期五的 09:38 -0700,Drew Fustini写道:
> On Fri, Jul 26, 2024 at 03:45:36AM -0500, Emil Renner Berthing wrote:
> > Stephen Boyd wrote:
> > > Quoting Drew Fustini (2024-06-23 19:12:31)
> > > > Document bindings for the T-Head TH1520 AP sub-system clock
> > > > controller.
> > > >
> > > > Link:
> > > > https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
> > > > Co-developed-by: Yangtao Li <frank.li@vivo.com>
> > > > Signed-off-by: Yangtao Li <frank.li@vivo.com>
> > > > Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
> > > > Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
> > > > ---
> > >
> > > Applied to clk-next
> >
> > Thanks, but this driver seems a bit incomplete. With this applied
> > the Lichee Pi
> > 4A no longer boots without the clk_ignore_unused kernel parameter.
> >
> > /Emil
>
> Is this the case when you apply the dts patches from this series?
>
> The dts patches won't go in until 6.12 so I don't think the presence
> of
> the clk-th1520-ap.c itself in 6.11 would break existing systems.
>
> That said, I have been using clk_ignore_unused. I had been thinking
> that
> made sense because the full set of clock controller drivers like
> AON_SUBSYS (always on), AUDIO_SUBSYS, DSP_SUBSYS, etc, are not
> present
> yet in mainline. However, the T-Head vendor kernel does have drivers
> for
> all those clock controllers and I was suprised to see that the vendor
> kernel fails to boot when I just tested removing clk_ignore_unused.
>
> As for clk-th1520-ap.c in mainline, I'll investigate further which
> clk
> disables seem to causing the boot failure when using the dts from
> this
> series. I suspect I may need to add nodes that will cause the
> necessary
> clks to be enabled by their respective drivers.
If disabling the clock just leads to system hang, setting
CLK_IS_CRITICAL should be useful (and needed) here.
>
> Thanks,
> Drew
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller
2024-07-27 5:21 ` Icenowy Zheng
@ 2024-07-30 23:05 ` Drew Fustini
0 siblings, 0 replies; 15+ messages in thread
From: Drew Fustini @ 2024-07-30 23:05 UTC (permalink / raw)
To: Icenowy Zheng, Emil Renner Berthing
Cc: Stephen Boyd, Albert Ou, Conor Dooley, Drew Fustini, Fu Wei,
Guo Ren, Jisheng Zhang, Krzysztof Kozlowski, Michael Turquette,
Palmer Dabbelt, Paul Walmsley, Rob Herring, Thomas Bonnefille,
Yangtao Li, linux-riscv, linux-clk, devicetree, linux-kernel,
Conor Dooley
On Sat, Jul 27, 2024 at 01:21:39PM +0800, Icenowy Zheng wrote:
> 在 2024-07-26星期五的 09:38 -0700,Drew Fustini写道:
> > On Fri, Jul 26, 2024 at 03:45:36AM -0500, Emil Renner Berthing wrote:
> > > Stephen Boyd wrote:
> > > > Quoting Drew Fustini (2024-06-23 19:12:31)
> > > > > Document bindings for the T-Head TH1520 AP sub-system clock
> > > > > controller.
> > > > >
> > > > > Link:
> > > > > https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
> > > > > Co-developed-by: Yangtao Li <frank.li@vivo.com>
> > > > > Signed-off-by: Yangtao Li <frank.li@vivo.com>
> > > > > Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
> > > > > Signed-off-by: Drew Fustini <dfustini@tenstorrent.com>
> > > > > ---
> > > >
> > > > Applied to clk-next
> > >
> > > Thanks, but this driver seems a bit incomplete. With this applied
> > > the Lichee Pi
> > > 4A no longer boots without the clk_ignore_unused kernel parameter.
> > >
> > > /Emil
> >
> > Is this the case when you apply the dts patches from this series?
> >
> > The dts patches won't go in until 6.12 so I don't think the presence
> > of
> > the clk-th1520-ap.c itself in 6.11 would break existing systems.
> >
> > That said, I have been using clk_ignore_unused. I had been thinking
> > that
> > made sense because the full set of clock controller drivers like
> > AON_SUBSYS (always on), AUDIO_SUBSYS, DSP_SUBSYS, etc, are not
> > present
> > yet in mainline. However, the T-Head vendor kernel does have drivers
> > for
> > all those clock controllers and I was suprised to see that the vendor
> > kernel fails to boot when I just tested removing clk_ignore_unused.
> >
> > As for clk-th1520-ap.c in mainline, I'll investigate further which
> > clk
> > disables seem to causing the boot failure when using the dts from
> > this
> > series. I suspect I may need to add nodes that will cause the
> > necessary
> > clks to be enabled by their respective drivers.
>
> If disabling the clock just leads to system hang, setting
> CLK_IS_CRITICAL should be useful (and needed) here.
Thank you for the suggestion about CLK_IS_CRITICAL.
I have found through process of elimination that the "emmc-sdio" clock
(CLK_EMMC_SDIO) fails to work after the "vp-axi" clock (CLK_VP_AXI) is
disabled. I added the CLK_IGNORE_UNUSED flag to "vp-axi" and the system
is able to boot correctly. I think in that case CLK_IS_CRITICAL is not
needed.
I've been reviewing the TH1520 System User Manual [1] and I am uncertain
why the state of "vp-axi" would affect "emmc-sdio":
- EMMC_SDIO_REF_CLK_EN is bit 30 in PERI_CLK_CFG (offset 0x204).
- VPSYS_AXI_ACLK_EN is bit 15 in VPSYS_CLK_CFG (offsset 0x1e0).
I don't see any linkage between them in the public documentation.
Regardless, the addition of the CLK_IGNORE_UNUSED flag to "vp-axi" fixes
the boot failure, so I will post a patch to that effect.
Thanks,
Drew
[1] https://openbeagle.org/beaglev-ahead/beaglev-ahead/-/blob/main/docs/TH1520%20System%20User%20Manual.pdf
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2024-07-30 23:05 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-24 2:12 [PATCH v2 0/7] clk: thead: Add support for TH1520 AP_SUBSYS clock controller Drew Fustini
2024-06-24 2:12 ` [PATCH v2 1/7] dt-bindings: clock: Document T-Head TH1520 AP_SUBSYS controller Drew Fustini
2024-07-10 23:17 ` Stephen Boyd
2024-07-26 8:45 ` Emil Renner Berthing
2024-07-26 16:38 ` Drew Fustini
2024-07-27 5:21 ` Icenowy Zheng
2024-07-30 23:05 ` Drew Fustini
2024-06-24 2:12 ` [PATCH v2 2/7] clk: thead: Add support for T-Head TH1520 AP_SUBSYS clocks Drew Fustini
2024-07-10 23:17 ` Stephen Boyd
2024-07-11 6:55 ` Drew Fustini
2024-06-24 2:12 ` [PATCH v2 3/7] riscv: dts: thead: Add TH1520 AP_SUBSYS clock controller Drew Fustini
2024-06-24 2:12 ` [PATCH v2 4/7] riscv: dts: thead: change TH1520 uart nodes to use " Drew Fustini
2024-06-24 2:12 ` [PATCH v2 5/7] riscv: dts: thead: change TH1520 mmc " Drew Fustini
2024-06-24 2:12 ` [PATCH v2 6/7] riscv: dts: thead: update TH1520 dma and timer " Drew Fustini
2024-06-24 2:12 ` [PATCH v2 7/7] riscv: dts: thead: add clock to TH1520 gpio nodes Drew Fustini
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).