* [PATCH 1/3] arm64: dts: add SC9860 clock tree data
2017-05-15 8:34 [PATCH 0/3] add clock driver for Spreadtrum platforms Chunyan Zhang
@ 2017-05-15 8:35 ` Chunyan Zhang
2017-05-15 8:35 ` [PATCH 2/3] Documentation: add sprd clock bindings Chunyan Zhang
2017-05-15 8:35 ` [PATCH 3/3] clk: Add common clock driver for Spreadtrum SoCs Chunyan Zhang
2 siblings, 0 replies; 8+ messages in thread
From: Chunyan Zhang @ 2017-05-15 8:35 UTC (permalink / raw)
To: linux-arm-kernel
From: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
This patch addresses SC9860 clock topology structure and provides clock
node to other devices (clock consumers) on chip.
This patch also removed replicated node of 26m fixed clock.
Signed-off-by: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
arch/arm64/boot/dts/sprd/sc9860-clocks.dtsi | 1984 +++++++++++++++++++++++++++
arch/arm64/boot/dts/sprd/sc9860.dtsi | 1 +
arch/arm64/boot/dts/sprd/whale2.dtsi | 7 -
3 files changed, 1985 insertions(+), 7 deletions(-)
create mode 100644 arch/arm64/boot/dts/sprd/sc9860-clocks.dtsi
diff --git a/arch/arm64/boot/dts/sprd/sc9860-clocks.dtsi b/arch/arm64/boot/dts/sprd/sc9860-clocks.dtsi
new file mode 100644
index 0000000..5756933
--- /dev/null
+++ b/arch/arm64/boot/dts/sprd/sc9860-clocks.dtsi
@@ -0,0 +1,1984 @@
+/*
+ * Spreadtrum SC9860 SoC DTS file
+ *
+ * Copyright (C) 2015, Spreadtrum Communications Inc.
+ *
+ * This file is licensed under a dual GPLv2 or X11 license.
+ */
+&soc {
+ aliases {
+ apb_pclk = &clk_ap_apb;
+ };
+
+ ext_26m: ext-26m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "ext_26m";
+ };
+
+ ext_32m_sine0: ext-32m-sine0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32000000>;
+ clock-output-names = "ext_32m_sine0";
+ };
+
+ ext_32m_sine1: ext-32m-sine1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32000000>;
+ clock-output-names = "ext_32m_sine1";
+ };
+
+ clk_pll_in: clk-pll-in {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "ext_26m";
+ };
+
+ clk_4m: clk-4m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <6>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_4m";
+ };
+
+ clk_2m: clk-2m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <13>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_2m";
+ };
+
+ clk_1m: clk-1m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <26>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_1m";
+ };
+
+ clk_250k: clk-250k {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <104>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_250k";
+ };
+
+ ext_rco_100m: ext-rco-100m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-output-names = "ext_rco_100m";
+ };
+
+ ext_32k: ext-32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "ext_32k";
+ };
+
+ clk_rpll0_26m: clk-rpll0-26m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_rpll0_26m";
+ };
+
+ clk_rpll1_26m: clk-rpll1-26m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_rpll1_26m";
+ };
+
+ clk_rpll_gates: clk at 402b016c {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402b016c 0 0x3000>;
+ clocks = <&ext_26m>;
+ clock-indices = <2>, <18>;
+ clock-output-names = "clk_rpll0_gate", "clk_rpll1_gate";
+ };
+
+ clk_mpll_gates: clk at 402b00b0 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402b00b0 0 0x3000>;
+ clocks = <&ext_26m>;
+ clock-indices = <2>, <18>;
+ clock-output-names = "clk_mpll0_gate", "clk_mpll1_gate";
+ };
+
+ clk_dpll_gates: clk at 402b00b4 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402b00b4 0 0x3000>;
+ clocks = <&ext_26m>;
+ clock-indices = <2>, <18>;
+ clock-output-names = "clk_dpll0_gate", "clk_dpll1_gate";
+ };
+
+ clk_gpll_gate: clk at 402b032c {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402b032d 0 0x3000>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_gpll_gate";
+ };
+
+ clk_cppll_gate: clk at 402b02b4 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402b02b4 0 0x3000>;
+ clocks = <&ext_26m>;
+ clock-indices = <2>;
+ clock-output-names = "clk_cppll_gate";
+ };
+
+ clk_ltepll0_gate: clk at 402b00b8 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402b00b8 0 0x3000>;
+ clocks = <&ext_26m>;
+ clock-indices = <2>;
+ clock-output-names = "clk_ltepll0_gate";
+ };
+
+ clk_ltepll1_gate: clk at 402b010c {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402b010c 0 0x3000>;
+ clocks = <&ext_26m>;
+ clock-indices = <2>;
+ clock-output-names = "clk_ltepll1_gate";
+ };
+
+ clk_twpll_gate: clk at 402b00bc {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402b00bc 0 0x3000>;
+ clocks = <&ext_26m>;
+ clock-indices = <2>;
+ clock-output-names = "clk_twpll_gate";
+ };
+
+ clk_rpll0: clk at 40400044 {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x40400044 0 0x4>,
+ <0 0x40400048 0 0x4>,
+ <0 0x4040004c 0 0x4>;
+ clocks = <&clk_rpll_gates 2>;
+ clock-output-names = "clk_rpll0";
+ };
+
+ clk_rpll1: clk at 40400050 {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x40400050 0 0x4>,
+ <0 0x40400054 0 0x4>,
+ <0 0x40400058 0 0x4>;
+ clocks = <&clk_rpll_gates 18>;
+ clock-output-names = "clk_rpll1";
+ };
+
+ clk_mpll0: clk at 40400024 {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x40400024 0 0x4>,
+ <0 0x40400028 0 0x4>;
+ clocks = <&clk_mpll_gates 2>;
+ clock-output-names = "clk_mpll0";
+ };
+
+ clk_mpll1: clk at 4040002c {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x4040002c 0 0x4>,
+ <0 0x40400030 0 0x4>;
+ clocks = <&clk_mpll_gates 18>;
+ clock-output-names = "clk_mpll1";
+ };
+
+ clk_dpll0: clk at 40400034 {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x40400034 0 0x4>,
+ <0 0x40400038 0 0x4>;
+ clocks = <&clk_dpll_gates 2>;
+ clock-output-names = "clk_dpll0";
+ };
+
+ clk_dpll1: clk at 4040003c {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x4040003c 0 0x4>,
+ <0 0x40400040 0 0x4>;
+ clocks = <&clk_dpll_gates 18>;
+ clock-output-names = "clk_dpll1";
+ };
+
+ clk_gpll: clk at 4040009c {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x4040009c 0 0x4>,
+ <0 0x404000a0 0 0x4>;
+ clocks = <&clk_gpll_gate>;
+ clock-output-names = "clk_gpll";
+ };
+
+ clk_cppll: clk at 404000c4 {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x404000c4 0 0x4>,
+ <0 0x404000c8 0 0x4>;
+ clocks = <&clk_cppll_gate 2>;
+ clock-output-names = "clk_cppll";
+ };
+
+ clk_ltepll0: clk at 40400064 {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x40400064 0 0x4>,
+ <0 0x40400068 0 0x4>;
+ clocks = <&clk_ltepll0_gate 2>;
+ clock-output-names = "clk_ltepll0";
+ };
+
+ clk_ltepll1: clk at 4040006c {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x4040006c 0 0x4>,
+ <0 0x40400070 0 0x4>;
+ clocks = <&clk_ltepll1_gate 2>;
+ clock-output-names = "clk_ltepll1";
+ };
+
+ clk_twpll: clk at 4040005c {
+ compatible = "sprd,sc9860-adjustable-pll-clock";
+ #clock-cells = <0>;
+ reg = <0 0x4040005c 0 0x4>,
+ <0 0x40400060 0 0x4>;
+ clocks = <&clk_twpll_gate 2>;
+ clock-output-names = "clk_twpll";
+ };
+
+ clk_gpll_42m5: clk-gpll-42m5 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <20>;
+ clocks = <&clk_gpll>;
+ clock-output-names = "clk_gpll_42m5";
+ };
+
+ clk_twpll_768m: clk-tw-768m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_768m";
+ };
+
+ clk_twpll_384m: clk-tw-384m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_384m";
+ };
+
+ clk_twpll_192m: clk-tw-192m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <8>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_192m";
+ };
+
+ clk_twpll_96m: clk-tw-96m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_96m";
+ };
+
+ clk_twpll_48m: clk-tw-48m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <32>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_48m";
+ };
+
+ clk_twpll_24m: clk-tw-24m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <64>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_24m";
+ };
+
+ clk_twpll_12m: clk-tw-12m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <128>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_12m";
+ };
+
+ clk_twpll_512m: clk-tw-512m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_512m";
+ };
+
+ clk_twpll_256m: clk-tw-256m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <6>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_256m";
+ };
+
+ clk_twpll_128m: clk-tw-128m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <12>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_128m";
+ };
+
+ clk_twpll_64m: clk-tw-64m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <24>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_64m";
+ };
+
+ clk_twpll_307m2: clk-tw-307m2 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <5>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_307m2";
+ };
+
+ clk_twpll_153m6: clk-tw-153m6 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <10>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_153m6";
+ };
+
+ clk_twpll_76m8: clk-tw-76m8 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <20>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_76m8";
+ };
+
+ clk_twpll_51m2: clk-tw-51m2 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <30>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_51m2";
+ };
+
+ clk_twpll_38m4: clk-tw-38m4 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <40>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_38m4";
+ };
+
+ clk_twpll_19m2: clk-tw-19m2 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <80>;
+ clocks = <&clk_twpll>;
+ clock-output-names = "clk_twpll_19m2";
+ };
+
+ clk_l0_614m4: clk-l0-614m4 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ clocks = <&clk_ltepll0>;
+ clock-output-names = "clk_l0_614m4";
+ };
+
+ clk_l0_38m: clk-l0-38m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <32>;
+ clocks = <&clk_ltepll0>;
+ clock-output-names = "clk_l0_38m";
+ };
+
+ clk_l0_409m6: clk-l0-409m6 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <3>;
+ clocks = <&clk_ltepll0>;
+ clock-output-names = "clk_l0_409m6";
+ };
+
+ clk_l1_38m: clk-l1-38m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <32>;
+ clocks = <&clk_ltepll1>;
+ clock-output-names = "clk_l1_38m";
+ };
+
+ clk_rpll0_192m: clk-rpll0-192m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <6>;
+ clocks = <&clk_rpll0>;
+ clock-output-names = "clk_rpll0_192m";
+ };
+
+ clk_rpll0_96m: clk-rpll0-96m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <12>;
+ clocks = <&clk_rpll0>;
+ clock-output-names = "clk_rpll0_96m";
+ };
+
+ clk_rpll0_48m: clk-rpll0-48m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <24>;
+ clocks = <&clk_rpll0>;
+ clock-output-names = "clk_rpll0_48m";
+ };
+
+ clk_rpll1_468m: clk-rpll1-468m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <2>;
+ clocks = <&clk_rpll1>;
+ clock-output-names = "clk_rpll1_468m";
+ };
+
+ clk_rpll1_192m: clk-rpll1-192m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <6>;
+ clocks = <&clk_rpll1>;
+ clock-output-names = "clk_rpll1_192m";
+ };
+
+ clk_rpll1_96m: clk-rpll1-96m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <12>;
+ clocks = <&clk_rpll1>;
+ clock-output-names = "clk_rpll1_96m";
+ };
+
+ clk_rpll1_64m: clk-rpll1-64m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <18>;
+ clocks = <&clk_rpll1>;
+ clock-output-names = "clk_rpll1_64m";
+ };
+
+ clk_rpll1_48m: clk-rpll1-48m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <24>;
+ clocks = <&clk_rpll1>;
+ clock-output-names = "clk_rpll1_48m";
+ };
+
+ clk_dpll0_50m: clk-dpll0-50m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ clocks = <&clk_dpll0>;
+ clock-output-names = "clk_dpll0_50m";
+ };
+
+ clk_dpll1_50m: clk-dpll1-50m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <16>;
+ clocks = <&clk_dpll1>;
+ clock-output-names = "clk_dpll1_50m";
+ };
+
+ clk_cppll_50m: clk-cppll-50m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <18>;
+ clocks = <&clk_cppll>;
+ clock-output-names = "clk_cppll_50m";
+ };
+
+ clk_rco_25m: clk-rco-25m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <4>;
+ clocks = <&ext_rco_100m>;
+ clock-output-names = "clk_rco_25m";
+ };
+
+ clk_rco_4m: clk-rco-4m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <25>;
+ clocks = <&ext_rco_100m>;
+ clock-output-names = "clk_rco_4m";
+ };
+
+ clk_rco_2m: clk-rco-2m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <50>;
+ clocks = <&ext_rco_100m>;
+ clock-output-names = "clk_rco_2m";
+ };
+
+ clk_3k2: clk-3k2 {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <10>;
+ clocks = <&ext_32k>;
+ clock-output-names = "clk_3k2";
+ };
+
+ clk_1k: clk-1k {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <32>;
+ clocks = <&ext_32k>;
+ clock-output-names = "clk_1k";
+ };
+
+ clk_aon_apb: clk at 402d0230 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0230 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ sprd,div-msk = <0x300>;
+ clocks = <&clk_rco_25m>, <&ext_26m>, <&ext_rco_100m>,
+ <&clk_twpll_96m>, <&clk_twpll_128m>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_aon_apb";
+ };
+
+ clk_adi: clk at 402d0234 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0234 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_rco_4m>, <&ext_26m>, <&clk_rco_25m>,
+ <&clk_twpll_38m4>, <&clk_twpll_51m2>;
+ clock-output-names = "clk_adi";
+ };
+
+ clk_m0_39m: clk-m0-39m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <32>;
+ clocks = <&clk_mpll0>;
+ clock-output-names = "clk_m0_39m";
+ };
+
+ clk_m1_63m: clk-m1-63m {
+ compatible = "fixed-factor-clock";
+ #clock-cells = <0>;
+ clock-mult = <1>;
+ clock-div = <32>;
+ clocks = <&clk_mpll1>;
+ clock-output-names = "clk_m1_63m";
+ };
+
+ clk_aux0: clk at 402d0238 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0238 0 0x4>;
+ sprd,mux-msk = <0x1f>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&ext_32k>, <&clk_rpll0_26m>, <&clk_rpll1_26m>,
+ <&ext_26m>, <&clk_cppll_50m>, <&clk_rco_25m>,
+ <&clk_dpll0_50m>, <&clk_dpll1_50m>, <&clk_gpll_42m5>,
+ <&clk_twpll_48m>, <&clk_m0_39m>, <&clk_m1_63m>,
+ <&clk_l0_38m>, <&clk_l1_38m>;
+ clock-output-names = "clk_aux0";
+ };
+
+ clk_aux1: clk at 402d023c {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d023c 0 0x4>;
+ sprd,mux-msk = <0x1f>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&ext_32k>, <&clk_rpll0_26m>, <&clk_rpll1_26m>,
+ <&ext_26m>, <&clk_cppll_50m>, <&clk_rco_25m>,
+ <&clk_dpll0_50m>, <&clk_dpll1_50m>, <&clk_gpll_42m5>,
+ <&clk_twpll_48m>, <&clk_m0_39m>, <&clk_m1_63m>,
+ <&clk_l0_38m>, <&clk_l1_38m>;
+ clock-output-names = "clk_aux1";
+ };
+
+ clk_aux2: clk at 402d0240 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0240 0 0x4>;
+ sprd,mux-msk = <0x1f>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&ext_32k>, <&clk_rpll0_26m>, <&clk_rpll1_26m>,
+ <&ext_26m>, <&clk_cppll_50m>, <&clk_rco_25m>,
+ <&clk_dpll0_50m>, <&clk_dpll1_50m>, <&clk_gpll_42m5>,
+ <&clk_twpll_48m>, <&clk_m0_39m>, <&clk_m1_63m>,
+ <&clk_l0_38m>, <&clk_l1_38m>;
+ clock-output-names = "clk_aux2";
+ };
+
+ clk_probe: clk at 402d0244 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0244 0 0x4>;
+ sprd,mux-msk = <0x1f>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&ext_32k>, <&clk_rpll0_26m>, <&clk_rpll1_26m>,
+ <&ext_26m>, <&clk_cppll_50m>, <&clk_rco_25m>,
+ <&clk_dpll0_50m>, <&clk_dpll1_50m>, <&clk_gpll_42m5>,
+ <&clk_twpll_48m>, <&clk_m0_39m>, <&clk_m1_63m>,
+ <&clk_l0_38m>, <&clk_l1_38m>;
+ clock-output-names = "clk_probe";
+ };
+
+ clk_pwm0: clk at 402d0248 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0248 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&ext_32k>, <&ext_26m>, <&clk_rco_4m>,
+ <&clk_rco_25m>, <&clk_twpll_48m>;
+ clock-output-names = "clk_pwm0";
+ };
+
+ clk_pwm1: clk at 402d024c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d024c 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&ext_32k>, <&ext_26m>, <&clk_rco_4m>,
+ <&clk_rco_25m>, <&clk_twpll_48m>;
+ clock-output-names = "clk_pwm1";
+ };
+
+ clk_pwm2: clk at 402d0250 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0250 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&ext_32k>, <&ext_26m>, <&clk_rco_4m>,
+ <&clk_rco_25m>, <&clk_twpll_48m>;
+ clock-output-names = "clk_pwm2";
+ };
+
+ clk_pwm3: clk at 402d0254 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0254 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&ext_32k>, <&ext_26m>, <&clk_rco_4m>,
+ <&clk_rco_25m>, <&clk_twpll_48m>;
+ clock-output-names = "clk_pwm3";
+ };
+
+ clk_efuse: clk at 402d0258 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0258 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&clk_rco_25m>, <&ext_26m>;
+ clock-output-names = "clk_efuse";
+ };
+
+ clk_cm3_uart0: clk at 402d025c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d025c 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_rco_4m>, <&ext_26m>,<&ext_rco_100m>,
+ <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_96m>, <&clk_twpll_128m>;
+ clock-output-names = "clk_cm3_uart0";
+ };
+
+ clk_cm3_uart1: clk at 402d0260 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0260 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_rco_4m>, <&ext_26m>,<&ext_rco_100m>,
+ <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_96m>, <&clk_twpll_128m>;
+ clock-output-names = "clk_cm3_uart1";
+ };
+
+ clk_thm: clk at 402d0270 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0270 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_32k>, <&clk_250k>;
+ clock-output-names = "clk_thm";
+ };
+
+ clk_cm3_i2c0: clk at 402d0274 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0274 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_rco_4m>, <&ext_26m>, <&ext_rco_100m>,
+ <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_cm3_i2c0";
+ };
+
+ clk_cm3_i2c1: clk at 402d0278 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0278 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_rco_4m>, <&ext_26m>, <&ext_rco_100m>,
+ <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_cm3_i2c1";
+ };
+
+ clk_cm4_spi: clk at 402d027c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d027c 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&ext_26m>, <&clk_twpll_96m>, <&ext_rco_100m>,
+ <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>;
+ clock-output-names = "clk_cm4_spi";
+ };
+
+ clk_aon_i2c: clk at 402d0280 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0280 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_rco_4m>, <&ext_26m>, <&ext_rco_100m>,
+ <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_aon_i2c";
+ };
+
+ clk_avs: clk at 402d0284 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0284 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_avs";
+ };
+
+ clk_ca53_dap: clk at 402d0288 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0288 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&ext_26m>, <&clk_rco_4m>, <&ext_rco_100m>,
+ <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_ca53_dap";
+ };
+
+ clk_ca53_ts: clk at 402d0290 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0290 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_32k>, <&ext_26m>, <&clk_twpll_128m>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_ca53_ts";
+ };
+
+ clk_26m_lvdsdis: clk at 402d0294 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0294 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_26m_lvdsdis";
+ };
+
+ clk_lvdsrf_cali: clk at 402d02b8 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02b8 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_lvdsrf_cali";
+ };
+
+ clk_mdar_chk: clk at 402d02bc {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02bc 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_mdar_chk";
+ };
+
+ clk_rco100m_ref: clk at 402d02c0 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02c0 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&clk_2m>;
+ clock-output-names = "clk_rco100m_ref";
+ };
+
+ clk_rco100m_fdk: clk at 402d02c4 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02c4 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&clk_rco_2m>;
+ clock-output-names = "clk_rco100m_fdk";
+ };
+
+ clk_djtag_tck: clk at 402d02c8 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02c8 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&clk_rco_4m>, <&ext_26m>;
+ clock-output-names = "clk_djtag_tck";
+ };
+
+ clk_sp_ahb: clk at 402d02d0 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02d0 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ sprd,div-msk = <0x300>;
+ clocks = <&clk_rco_4m>, <&ext_26m>, <&ext_rco_100m>,
+ <&clk_twpll_96m>, <&clk_twpll_128m>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_sp_ahb";
+ };
+
+ clk_det_32k: clk at 402d02dc {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02dc 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&clk_rco_4m>;
+ clock-output-names = "clk_det_32k";
+ };
+
+ clk_pmu: clk at 402d02e0 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02e0 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_32k>, <&clk_rco_4m>, <&clk_4m>;
+ clock-output-names = "clk_pmu";
+ };
+
+ clk_pmu_26m: clk at 402d02e4 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02e4 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&clk_rco_25m>, <&ext_26m>;
+ clock-output-names = "clk_pmu_26m";
+ };
+
+ clk_debounce: clk at 402d02e8 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02e8 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_32k>, <&clk_rco_4m>,
+ <&clk_rco_25m>, <&ext_26m>;
+ clock-output-names = "clk_debounce";
+ };
+
+ clk_dphy_ref: clk at 402d02f0 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02f0 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_dphy_ref";
+ };
+
+ clk_otg2_ref: clk at 402d02f4 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02f4 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&clk_twpll_12m>, <&clk_twpll_24m>;
+ clock-output-names = "clk_otg2_ref";
+ };
+
+ clk_usb3_ref: clk at 402d02f8 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02f8 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_24m>, <&clk_twpll_19m2>, <&clk_twpll_48m>;
+ clock-output-names = "clk_usb3_ref";
+ };
+
+ clk_usb3_suspend: clk at 402d02fc {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d02fc 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_32k>, <&clk_1m>;
+ clock-output-names = "clk_usb3_suspend";
+ };
+
+ clk_cci: clk at 402d0300 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0300 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x300>;
+ clocks = <&ext_26m>, <&clk_twpll_384m>, <&clk_l0_614m4>,
+ <&clk_twpll_768m>;
+ clock-output-names = "clk_cci";
+ };
+
+ clk_gic: clk at 402d0304 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0304 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x300>;
+ clocks = <&ext_26m>, <&clk_twpll_384m>, <&clk_l0_614m4>,
+ <&clk_twpll_768m>;
+ clock-output-names = "clk_gic";
+ };
+
+ clk_ap_axi: clk at 402d0324 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0324 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_26m>, <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>;
+ clock-output-names = "clk_ap_axi";
+ };
+
+ clk_sdio_gates: clk at 402e013c {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402e013c 0 0x3000>;
+ clock-indices = <2>, <3>,
+ <4>, <5>, <6>, <7>,
+ <8>, <9>;
+ clock-output-names = "sdio0_2x_en", "sdio0_1x_en",
+ "sdio1_2x_en", "sdio1_1x_en",
+ "sdio2_2x_en", "sdio2_1x_en",
+ "emmc_1x_en", "emmc_2x_en";
+ };
+
+ clk_sdio0_2x: clk at 402d0328 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0328 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&clk_1m>, <&ext_26m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>, <&clk_l0_409m6>;
+ clock-output-names = "clk_sdio0_2x";
+ };
+
+ clk_sdio0_1x: clk at 402d032c {
+ compatible = "sprd,divider-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d032c 0 0x4>;
+ sprd,div-msk = <0x100>;
+ clocks = <&clk_sdio0_2x>;
+ clock-output-names = "clk_sdio0_1x";
+ };
+
+ clk_sdio1_2x: clk at 402d0330 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0330 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&clk_1m>, <&ext_26m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>, <&clk_l0_409m6>;
+ clock-output-names = "clk_sdio1_2x";
+ };
+
+ clk_sdio1_1x: clk at 402d0334 {
+ compatible = "sprd,divider-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0334 0 0x4>;
+ sprd,div-msk = <0x100>;
+ clocks = <&clk_sdio1_2x>;
+ clock-output-names = "clk_sdio1_1x";
+ };
+
+ clk_sdio2_2x: clk at 402d0338 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0338 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&clk_1m>, <&ext_26m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>, <&clk_l0_409m6>;
+ clock-output-names = "clk_sdio2_2x";
+ };
+
+ clk_sdio2_1x: clk at 402d033c {
+ compatible = "sprd,divider-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d033c 0 0x4>;
+ sprd,div-msk = <0x100>;
+ clocks = <&clk_sdio2_2x>;
+ clock-output-names = "clk_sdio2_1x";
+ };
+
+ clk_emmc_2x: clk at 402d0340 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0340 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&clk_1m>, <&ext_26m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>, <&clk_l0_409m6>;
+ clock-output-names = "clk_emmc_2x";
+ };
+
+ clk_emmc_1x: clk at 402d0344 {
+ compatible = "sprd,divider-clock";
+ #clock-cells = <0>;
+ reg = <0 0x402d0344 0 0x4>;
+ sprd,div-msk = <0x100>;
+ clocks = <&clk_emmc_2x>;
+ clock-output-names = "clk_emmc_1x";
+ };
+
+ clk_ap_apb: clk at 20000020 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000020 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_26m>, <&clk_twpll_64m>, <&clk_twpll_96m>,
+ <&clk_twpll_128m>;
+ clock-output-names = "clk_ap_apb";
+ };
+
+ clk_ap_usb3_ref: clk at 2000002c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x2000002c 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_32k>, <&clk_twpll_24m>;
+ clock-output-names = "clk_ap_usb3_ref";
+ };
+
+ clk_uart0: clk at 20000030 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000030 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_uart0";
+ };
+
+ clk_uart1: clk at 20000034 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000034 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_uart1";
+ };
+
+ clk_uart2: clk at 20000038 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000038 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_uart2";
+ };
+
+ clk_uart3: clk at 2000003c {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x2000003c 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_uart3";
+ };
+
+ clk_uart4: clk at 20000040 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000040 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_uart4";
+ };
+
+ clk_i2c0: clk at 20000044 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000044 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_i2c0";
+ };
+
+ clk_i2c1: clk at 20000048 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000048 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_i2c1";
+ };
+
+ clk_i2c2: clk at 2000004c {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x2000004c 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_i2c2";
+ };
+
+ clk_i2c3: clk at 20000050 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000050 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_i2c3";
+ };
+
+ clk_i2c4: clk at 20000054 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000054 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_i2c4";
+ };
+
+ clk_i2c5: clk at 20000058 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000058 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_51m2>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_i2c5";
+ };
+
+ clk_spi0: clk at 2000005c {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x2000005c 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>;
+ clock-output-names = "clk_spi0";
+ };
+
+ clk_spi1: clk at 20000060 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000060 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>;
+ clock-output-names = "clk_spi1";
+ };
+
+ clk_spi2: clk at 20000064 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000064 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>;
+ clock-output-names = "clk_spi2";
+ };
+
+ clk_spi3: clk at 20000068 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000068 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>;
+ clock-output-names = "clk_spi3";
+ };
+
+ clk_iis0: clk at 2000006c {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x2000006c 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x3f00>;
+ clocks = <&ext_26m>, <&clk_twpll_128m>, <&clk_twpll_153m6>;
+ clock-output-names = "clk_iis0";
+ };
+
+ clk_iis1: clk at 20000070 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000070 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x3f00>;
+ clocks = <&ext_26m>, <&clk_twpll_128m>, <&clk_twpll_153m6>;
+ clock-output-names = "clk_iis1";
+ };
+
+ clk_iis2: clk at 20000074 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000074 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x3f00>;
+ clocks = <&ext_26m>, <&clk_twpll_128m>, <&clk_twpll_153m6>;
+ clock-output-names = "clk_iis2";
+ };
+
+ clk_iis3: clk at 20000078 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x20000078 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x3f00>;
+ clocks = <&ext_26m>, <&clk_twpll_128m>, <&clk_twpll_153m6>;
+ clock-output-names = "clk_iis3";
+ };
+
+ clk_big_mcu: clk at 40880024 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x40880024 0 0x4>;
+ sprd,mux-msk = <0xf>;
+ sprd,div-msk = <0x70>;
+ clocks = <&ext_26m>, <&clk_twpll_512m>, <&clk_twpll_768m>,
+ <&clk_ltepll0>, <&clk_twpll>, <&clk_twpll>,
+ <&clk_twpll>, <&clk_twpll>, <&clk_mpll1>;
+ clock-output-names = "clk_big_mcu";
+ };
+
+ clk_lit_mcu: clk at 40880020 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x40880020 0 0x4>;
+ sprd,mux-msk = <0xf>;
+ sprd,div-msk = <0x70>;
+ clocks = <&ext_26m>, <&clk_twpll_512m>, <&clk_twpll_768m>,
+ <&clk_ltepll0>, <&clk_twpll>, <&clk_twpll>,
+ <&clk_twpll>, <&clk_twpll>, <&clk_mpll0>;
+ clock-output-names = "clk_lit_mcu";
+ };
+
+ /* gpu domain */
+ clk_gpu: clk at 60200020 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x60200020 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0xf00>;
+ clocks = <&clk_twpll_512m>, <&clk_twpll_768m>, <&clk_gpll>;
+ clock-output-names = "clk_gpu";
+ };
+
+ /* vsp domain */
+ clk_ahb_vsp: clk at 61000020 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x61000020 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_26m>, <&clk_twpll_96m>, <&clk_twpll_128m>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_ahb_vsp";
+ };
+
+ clk_vsp: clk at 61000024 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x61000024 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ sprd,div-msk = <0x300>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>;
+ clock-output-names = "clk_vsp";
+ };
+
+ clk_vsp_enc: clk at 61000028 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x61000028 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x300>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>;
+ clock-output-names = "clk_vsp_enc";
+ };
+
+ clk_vpp: clk at 6100002c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x6100002c 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_96m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>, <&clk_twpll_256m>;
+ clock-output-names = "clk_vpp";
+ };
+
+ clk_vsp_26m: clk at 61000030 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x61000030 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_vsp_26m";
+ };
+
+ clk_ahb_disp: clk at 63000020 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x63000020 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_26m>, <&clk_twpll_96m>, <&clk_twpll_128m>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_ahb_disp";
+ };
+
+ clk_gsp0: clk at 63000024 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x63000024 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_256m>, <&clk_twpll_307m2>,
+ <&clk_twpll_512m>, <&clk_l0_614m4>;
+ clock-output-names = "clk_gsp0";
+ };
+
+ clk_gsp1: clk at 63000028 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x63000028 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_256m>, <&clk_twpll_307m2>,
+ <&clk_twpll_512m>, <&clk_l0_614m4>;
+ clock-output-names = "clk_gsp1";
+ };
+
+ clk_dispc0: clk at 6300002c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x6300002c 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_192m>, <&clk_twpll_256m>,
+ <&clk_twpll_384m>, <&clk_twpll_512m>;
+ clock-output-names = "clk_dispc0";
+ };
+
+ clk_dispc0_dbi: clk at 63000030 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x63000030 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>, <&clk_twpll_256m>;
+ clock-output-names = "clk_dispc0_dbi";
+ };
+
+ clk_dispc0_dpi: clk at 63000034 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x63000034 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x300>;
+ clocks = <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>, <&clk_twpll_256m>;
+ clock-output-names = "clk_dispc0_dpi";
+ };
+
+ clk_dispc1: clk at 63000038 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x63000038 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_192m>, <&clk_twpll_256m>,
+ <&clk_twpll_384m>, <&clk_twpll_512m>;
+ clock-output-names = "clk_dispc1";
+ };
+
+ clk_dispc1_dbi: clk at 6300003c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x6300003c 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>, <&clk_twpll_256m>;
+ clock-output-names = "clk_dispc1_dbi";
+ };
+
+ clk_dispc1_dpi: clk at 63000040 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x63000040 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x300>;
+ clocks = <&clk_twpll_128m>, <&clk_twpll_153m6>,
+ <&clk_twpll_192m>, <&clk_twpll_256m>;
+ clock-output-names = "clk_dispc1_dpi";
+ };
+
+ clk_dphy0: clk at 6300004c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x6300004c 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_dphy0";
+ };
+
+ clk_dphy1: clk at 63000058 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x63000058 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_dphy1";
+ };
+
+ clk_ahb_cam: clk at 62000020 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000020 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_26m>, <&clk_twpll_96m>, <&clk_twpll_128m>,
+ <&clk_twpll_153m6>;
+ clock-output-names = "clk_ahb_cam";
+ };
+
+ clk_sensor0: clk at 62000024 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000024 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_76m8>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_sensor0";
+ };
+
+ clk_sensor1: clk at 62000028 {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000028 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_76m8>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_sensor1";
+ };
+
+ clk_sensor2: clk at 6200002c {
+ compatible = "sprd,composite-clock";
+ #clock-cells = <0>;
+ reg = <0 0x6200002c 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ sprd,div-msk = <0x700>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_76m8>,
+ <&clk_twpll_96m>;
+ clock-output-names = "clk_sensor2";
+ };
+
+ clk_dcam0: clk at 62000030 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000030 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_153m6>,
+ <&clk_twpll_307m2>, <&clk_twpll_384m>;
+ clock-output-names = "clk_dcam0";
+ };
+
+ clk_dcam1: clk at 62000034 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000034 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>;
+ clock-output-names = "clk_dcam1";
+ };
+
+ clk_dcam0_if: clk at 62000038 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000038 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_256m>,
+ <&clk_twpll_307m2>, <&clk_twpll_384m>,
+ <&clk_twpll_512m>;
+ clock-output-names = "clk_dcam0_if";
+ };
+
+ clk_isp0: clk at 6200003c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x6200003c 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_256m>,
+ <&clk_twpll_307m2>, <&clk_twpll_384m>,
+ <&clk_twpll_512m>;
+ clock-output-names = "clk_isp0";
+ };
+
+ clk_isp1: clk at 62000040 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000040 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_256m>,
+ <&clk_twpll_307m2>, <&clk_twpll_384m>,
+ <&clk_twpll_512m>;
+ clock-output-names = "clk_isp1";
+ };
+
+ clk_jpg0: clk at 62000044 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000044 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>;
+ clock-output-names = "clk_jpg0";
+ };
+
+ clk_jpg1: clk at 62000048 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000048 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>;
+ clock-output-names = "clk_jpg1";
+ };
+
+ clk_mipi_csi0_gate: clk at 6200004c {
+ compatible = "sprd,gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x6200004c 0 0x4>;
+ clock-indices = <16>;
+ clocks = <&clk_ahb_cam>;
+ clock-output-names = "mipi_csi0_eb";
+ };
+
+ clk_mipi_csi1_gate: clk at 62000050 {
+ compatible = "sprd,gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x62000050 0 0x4>;
+ clock-indices = <16>;
+ clocks = <&clk_ahb_cam>;
+ clock-output-names = "mipi_csi1_eb";
+ };
+
+ clk_cpp: clk at 6200005c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x6200005c 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>;
+ clock-output-names = "clk_cpp";
+ };
+
+ clk_isp_mclk: clk at 62000060 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000060 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>;
+ clock-output-names = "clk_isp_mclk";
+ };
+
+ clk_isp_pclk: clk at 62000064 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000064 0 0x4>;
+ sprd,mux-msk = <0x3>;
+ clocks = <&ext_26m>, <&clk_twpll_48m>, <&clk_twpll_76m8>;
+ clock-output-names = "clk_isp_pclk";
+ };
+
+ clk_isp_iclk: clk at 62000068 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000068 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_256m>,
+ <&clk_twpll_307m2>, <&clk_twpll_384m>,
+ <&clk_twpll_512m>;
+ clock-output-names = "clk_isp_iclk";
+ };
+
+ clk_isp_lclk: clk at 6200006c {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x6200006c 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>;
+ clock-output-names = "clk_isp_lclk";
+ };
+
+ clk_isp2: clk at 62000070 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000070 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_128m>,
+ <&clk_twpll_256m>, <&clk_twpll_307m2>,
+ <&clk_twpll_384m>;
+ clock-output-names = "clk_isp2";
+ };
+
+ clk_isp2dcam: clk at 62000074 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000074 0 0x4>;
+ sprd,mux-msk = <0x7>;
+ clocks = <&clk_twpll_76m8>, <&clk_twpll_153m6>,
+ <&clk_twpll_307m2>, <&clk_twpll_384m>;
+ clock-output-names = "clk_isp2dcam";
+ };
+
+ clk_cam_26m: clk at 62000078 {
+ compatible = "sprd,muxed-clock";
+ #clock-cells = <0>;
+ reg = <0 0x62000078 0 0x4>;
+ sprd,mux-msk = <0x1>;
+ clocks = <&ext_26m>;
+ clock-output-names = "clk_cam_26m";
+ };
+
+ clk_ap_ahb_gates: clk at 20210000 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x20210000 0 0x3000>;
+ clock-indices = <2>, <3>, <4>, <5>,
+ <7>, <8>, <9>, <10>,
+ <12>, <13>, <22>,
+ <23>, <24>, <25>;
+ clocks = <&clk_ap_axi>;
+ clock-output-names = "usb3_eb", "usb3_suspend_eb",
+ "usb3_ref_eb", "dma_eb",
+ "sdio0_eb", "sdio1_eb",
+ "sdio2_eb", "emmc_eb",
+ "rom_eb", "busmon_eb",
+ "cc63s_eb", "cc63p_eb",
+ "ce0_eb", "ce1_eb";
+ };
+
+ clk_aon_apb_gates0: clk at 402e0000 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402e0000 0 0x3000>;
+ clocks = <&clk_aon_apb>;
+ clock-output-names = "avs_ca53_lit_eb", "avs_ca53_big_eb",
+ "ap_intc5_eb", "gpio_eb",
+ "pwm0_eb", "pwm1_eb",
+ "pwm2_eb", "pwm3_eb",
+ "kpd_eb", "aon_syst_eb",
+ "ap_syst_eb", "aon_tmr_eb",
+ "ap_tmr0_eb", "efuse_eb",
+ "eic_eb", "pub1_reg_eb",
+ "adi_eb", "ap_intc0_eb",
+ "ap_intc1_eb", "ap_intc2_eb",
+ "ap_intc3_eb", "ap_intc4_eb",
+ "splk_eb", "mspi_eb",
+ "pub0_reg_eb", "pin_eb",
+ "aon_ckg_eb", "gpu_eb",
+ "apcpu_ts0_eb", "apcpu_ts1_eb",
+ "dap_eb", "i2c_eb";
+ };
+
+ clk_aon_apb_gates1: clk at 402e0004 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x402e0004 0 0x3000>;
+ clocks = <&clk_aon_apb>;
+ clock-output-names = "pmu_eb", "thm_eb",
+ "aux0_eb", "aux1_eb",
+ "aux2_eb", "probe_eb",
+ "gpu0_avs_eb", "gpu1_avs_eb",
+ "apcpu_wdg_eb", "ap_tmr1_eb",
+ "ap_tmr2_eb", "disp_emc_eb",
+ "zip_emc_eb", "gsp_emc_eb",
+ "osc_aon_eb", "lvds_trx_eb",
+ "lvds_tcxo_eb", "mdar_eb",
+ "rtc4m0_cal_eb", "rct100m_cal_eb",
+ "djtag_eb", "mbox_eb",
+ "aon_dma_eb", "dbg_emc_eb",
+ "lvds_pll_div_en", "def_eb",
+ "aon_apb_gate1_rsv0", "orp_jtag_eb",
+ "vsp_eb", "cam_eb",
+ "disp_eb", "dbg_axi_if_eb";
+ };
+
+ clk_agcp_ahb_gates: clk at 415e0000 {
+ compatible = "sprd,sc100-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x415e0000 0 0x300>;
+ clock-indices = <0>, <1>, <2>, <3>,
+ <4>, <5>, <6>,
+ <10>, <11>,
+ <12>, <13>, <14>, <15>,
+ <16>, <17>, <18>, <19>,
+ <20>;
+ clock-output-names = "agcp_iis0_eb", "agcp_iis1_eb",
+ "agcp_iis2_eb", "agcp_iis3_eb",
+ "agcp_uart_eb", "agcp_dmacp_eb",
+ "agcp_dmaap_eb", "agcp_arc48k_eb",
+ "agcp_src44p1k_eb", "agcp_mcdt_eb",
+ "agcp_vbcifd_eb", "agcp_vbc_eb",
+ "agcp_spinlock_eb", "agcp_icu_eb",
+ "agcp_ap_ashb_eb", "agcp_cp_ashb_eb",
+ "agcp_aud_eb", "agcp_audif_eb";
+ };
+
+ clk_ahb_vsp_gates: clk at 61100000 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x61100000 0 0x3000>;
+ clocks = <&clk_ahb_vsp>;
+ clock-output-names = "vsp_dec_eb", "vsp_ckg_eb",
+ "vsp_mmu_eb", "vsp_enc_eb",
+ "vpp_eb", "vsp_26m_eb";
+ };
+
+ clk_vsp_axi_gates: clk at 61100008 {
+ compatible = "sprd,gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x61100008 0 0x4>;
+ clock-indices = <0>, <1>, <2>,
+ <8>, <9>, <10>;
+ clocks = <&clk_ahb_vsp>;
+ clock-output-names = "vsp_axi_gate", "vsp_enc_gate",
+ "vpp_axi_gate", "vsp_bm_gate",
+ "vsp_enc_bm_gate", "vpp_bm_gate";
+ };
+
+ clk_ahb_cam_gates: clk at 62100000 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x62100000 0 0x3000>;
+ clocks = <&clk_ahb_cam>;
+ clock-output-names = "dcam0_eb", "dcam1_eb",
+ "isp0_eb", "csi0_eb",
+ "csi1_eb", "jpg0_eb",
+ "jpg1_eb", "cam_ckg_eb",
+ "cam_mmu_eb", "isp1_eb",
+ "cpp_eb", "mmu_pf_eb",
+ "isp2_eb", "dcam2isp_if_eb",
+ "isp2dcam_if_eb", "isp_lclk_eb",
+ "isp_iclk_eb", "isp_mclk_eb",
+ "isp_pclk_eb", "isp_isp2dcam_eb",
+ "dcam0_if_eb", "clk26m_if_eb";
+ };
+
+ clk_cam_axi_gates: clk at 62100008 {
+ compatible = "sprd,gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x62100008 0 0x4>;
+ clocks = <&clk_ahb_cam>;
+ clock-output-names = "cphy0_gate", "mipi_csi0_gate",
+ "cphy1_gate", "mipi_csi1",
+ "dcam0_axi_gate", "dcam1_axi_gate",
+ "sensor0_gate", "sensor1_gate",
+ "jpg0_axi_gate", "gpg1_axi_gate",
+ "isp0_axi_gate", "isp1_axi_gate",
+ "isp2_axi_gate", "cpp_axi_gate",
+ "d0_if_axi_gate", "d2i_if_axi_gate",
+ "i2d_if_axi_gate", "spare_axi_gate",
+ "sensor2_gate";
+ };
+
+ clk_cam_module_gates: clk at 62100028 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x62100028 0 0x3000>;
+ clocks = <&clk_ahb_cam>;
+ clock-output-names = "d0if_in_d_en", "d1if_in_d_en",
+ "d0if_in_d2i_en", "d1if_in_d2i_en",
+ "ia_in_d2i_en", "ib_in_d2i_en",
+ "ic_in_d2i_en", "ia_in_i_en",
+ "ib_in_i_en", "ic_in_i_en";
+ };
+
+ clk_ahb_disp_gates: clk at 63100000 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x63100000 0 0x3000>;
+ clock-indices = <0>, <1>, <2>, <3>,
+ <4>, <5>, <6>, <7>,
+ <8>, <9>, <10>,
+ <13>, <14>, <15>,
+ <16>;
+ clocks = <&clk_ahb_disp>;
+ clock-output-names = "dispc0_eb", "dispc1_eb",
+ "dispc_mmu_eb", "gsp0_eb",
+ "gsp1_eb", "gsp0_mmu_eb",
+ "gsp1_mmu_eb", "dsi0_eb",
+ "dsi1_eb", "disp_ckg_eb",
+ "disp_gpu_eb", "gpu_mtx_eb",
+ "gsp_mtx_eb", "tmc_mtx_eb",
+ "dispc_mtx_eb";
+ };
+
+ clk_disp_axi_gates: clk at 63100008 {
+ compatible = "sprd,gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x63100008 0 0x4>;
+ clocks = <&clk_ahb_disp>;
+ clock-output-names = "dphy0_gate", "dphy1_gate",
+ "gsp0_a_gate", "gsp1_a_gate",
+ "gsp0_f_gate", "gsp1_f_gate",
+ "d_mtx_f_gate", "d_mtx_a_gate",
+ "d_noc_f_gate", "d_noc_a_gate",
+ "gsp_mtx_f_gate", "gsp_mtx_a_gate",
+ "gsp_noc_f_gate", "gsp_noc_a_gate",
+ "dispm0idle_gate", "gspm0idle_gate";
+ };
+
+ clk_ap_apb_gates: clk at 70b00000 {
+ compatible = "sprd,sc1000-gates-clock";
+ #clock-cells = <1>;
+ reg = <0 0x70b00000 0 0x3000>;
+ clocks = <&clk_ap_apb>;
+ clock-output-names = "sim0_eb", "iis0_eb",
+ "iis1_eb", "iis2_eb",
+ "iis3_eb", "spi0_eb",
+ "spi1_eb", "spi2_eb",
+ "i2c0_eb", "i2c1_eb",
+ "i2c2_eb", "i2c3_eb",
+ "i2c4_eb", "i2c5_eb",
+ "uart0_eb", "uart1_eb",
+ "uart2_eb", "uart3_eb",
+ "uart4_eb", "ap_ckg_eb",
+ "spi3_eb";
+ };
+};
diff --git a/arch/arm64/boot/dts/sprd/sc9860.dtsi b/arch/arm64/boot/dts/sprd/sc9860.dtsi
index 7b7d8ce..97794fe 100644
--- a/arch/arm64/boot/dts/sprd/sc9860.dtsi
+++ b/arch/arm64/boot/dts/sprd/sc9860.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "whale2.dtsi"
+#include "sc9860-clocks.dtsi"
/ {
cpus {
diff --git a/arch/arm64/boot/dts/sprd/whale2.dtsi b/arch/arm64/boot/dts/sprd/whale2.dtsi
index cd5a71f..8d1f8aa 100644
--- a/arch/arm64/boot/dts/sprd/whale2.dtsi
+++ b/arch/arm64/boot/dts/sprd/whale2.dtsi
@@ -79,11 +79,4 @@
};
};
-
- ext_26m: ext-26m {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <26000000>;
- clock-output-names = "ext_26m";
- };
};
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] clk: Add common clock driver for Spreadtrum SoCs
2017-05-15 8:34 [PATCH 0/3] add clock driver for Spreadtrum platforms Chunyan Zhang
2017-05-15 8:35 ` [PATCH 1/3] arm64: dts: add SC9860 clock tree data Chunyan Zhang
2017-05-15 8:35 ` [PATCH 2/3] Documentation: add sprd clock bindings Chunyan Zhang
@ 2017-05-15 8:35 ` Chunyan Zhang
2 siblings, 0 replies; 8+ messages in thread
From: Chunyan Zhang @ 2017-05-15 8:35 UTC (permalink / raw)
To: linux-arm-kernel
From: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
This patch adds an initial common clock driver comprising clock gate,
divider, multiplexer, composite, pll, these drivers are used on almost
all Spreadtrum platforms so far.
Signed-off-by: Xiaolong Zhang <xiaolong.zhang@spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
---
drivers/clk/Makefile | 1 +
drivers/clk/sprd/Makefile | 3 +
drivers/clk/sprd/clk-gates.c | 366 ++++++++++++++++++++++++++++++++++++++++
drivers/clk/sprd/composite.c | 109 ++++++++++++
drivers/clk/sprd/divider.c | 79 +++++++++
drivers/clk/sprd/mux.c | 77 +++++++++
drivers/clk/sprd/pll.c | 359 +++++++++++++++++++++++++++++++++++++++
drivers/clk/sprd/pll.h | 73 ++++++++
drivers/clk/sprd/pll_cfg.h | 390 +++++++++++++++++++++++++++++++++++++++++++
9 files changed, 1457 insertions(+)
create mode 100644 drivers/clk/sprd/Makefile
create mode 100644 drivers/clk/sprd/clk-gates.c
create mode 100644 drivers/clk/sprd/composite.c
create mode 100644 drivers/clk/sprd/divider.c
create mode 100644 drivers/clk/sprd/mux.c
create mode 100644 drivers/clk/sprd/pll.c
create mode 100644 drivers/clk/sprd/pll.h
create mode 100644 drivers/clk/sprd/pll_cfg.h
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c19983a..1d62721 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
obj-$(CONFIG_ARCH_SIRF) += sirf/
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
obj-$(CONFIG_PLAT_SPEAR) += spear/
+obj-$(CONFIG_ARCH_SPRD) += sprd/
obj-$(CONFIG_ARCH_STI) += st/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/
diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
new file mode 100644
index 0000000..a783c27
--- /dev/null
+++ b/drivers/clk/sprd/Makefile
@@ -0,0 +1,3 @@
+ifneq ($(CONFIG_OF),)
+obj-y += divider.o mux.o composite.o pll.o clk-gates.o
+endif
diff --git a/drivers/clk/sprd/clk-gates.c b/drivers/clk/sprd/clk-gates.c
new file mode 100644
index 0000000..8d4ccb9
--- /dev/null
+++ b/drivers/clk/sprd/clk-gates.c
@@ -0,0 +1,366 @@
+/*
+ * Spreadtrum clock set/clear gate driver
+ *
+ * Copyright (C) 2015~2017 spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/spinlock.h>
+#include <linux/hwspinlock.h>
+
+DEFINE_SPINLOCK(gate_lock);
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+#define CLK_GATE_HWSPINLOCK BIT(7)
+#define GLB_CLK_HWSPINLOCK_TIMEOUT 5000
+
+static struct hwspinlock *glb_clk_hw_lock;
+
+static void sprd_clk_lock(struct clk_gate *gate,
+ unsigned long flags)
+{
+ if (gate->lock)
+ spin_lock_irqsave(gate->lock, flags);
+ else
+ __acquire(gate->lock);
+}
+
+static void sprd_clk_unlock(struct clk_gate *gate,
+ unsigned long flags)
+{
+ if (gate->lock)
+ spin_unlock_irqrestore(gate->lock, flags);
+ else
+ __release(gate->lock);
+}
+
+static void sprd_clk_hw_lock(struct clk_gate *gate,
+ unsigned long *flags)
+{
+ int ret = 0;
+
+ if (glb_clk_hw_lock && (gate->flags & CLK_GATE_HWSPINLOCK)) {
+ ret = hwspin_lock_timeout_irqsave(glb_clk_hw_lock,
+ GLB_CLK_HWSPINLOCK_TIMEOUT,
+ flags);
+ if (ret)
+ pr_err("glb_clk:%s lock the hwlock failed.\n",
+ __clk_get_name(gate->hw.clk));
+ return;
+ }
+
+ sprd_clk_lock(gate, *flags);
+}
+
+static void sprd_clk_hw_unlock(struct clk_gate *gate,
+ unsigned long *flags)
+{
+ if (glb_clk_hw_lock && (gate->flags & CLK_GATE_HWSPINLOCK)) {
+ hwspin_unlock_irqrestore(glb_clk_hw_lock, flags);
+ return;
+ }
+
+ sprd_clk_unlock(gate, *flags);
+}
+
+static void sprd_clk_gate_endisable(struct clk_hw *hw, int enable)
+{
+ struct clk_gate *gate = to_clk_gate(hw);
+ int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
+ unsigned long flags = 0;
+ u32 reg;
+
+ set ^= enable;
+
+ sprd_clk_hw_lock(gate, &flags);
+
+ reg = clk_readl(gate->reg);
+
+ if (set)
+ reg |= BIT(gate->bit_idx);
+ else
+ reg &= ~BIT(gate->bit_idx);
+
+ clk_writel(reg, gate->reg);
+
+ sprd_clk_hw_unlock(gate, &flags);
+}
+
+static int sprd_clk_gate_enable(struct clk_hw *hw)
+{
+ sprd_clk_gate_endisable(hw, 1);
+
+ return 0;
+}
+
+static void sprd_clk_gate_disable(struct clk_hw *hw)
+{
+ sprd_clk_gate_endisable(hw, 0);
+}
+
+static int sprd_clk_gate_is_enabled(struct clk_hw *hw)
+{
+ u32 reg;
+ struct clk_gate *gate = to_clk_gate(hw);
+
+ reg = clk_readl(gate->reg);
+
+ if (gate->flags & CLK_GATE_SET_TO_DISABLE)
+ reg ^= BIT(gate->bit_idx);
+
+ reg &= BIT(gate->bit_idx);
+
+ return reg ? 1 : 0;
+}
+
+const struct clk_ops sprd_clk_gate_ops = {
+ .enable = sprd_clk_gate_enable,
+ .disable = sprd_clk_gate_disable,
+ .is_enabled = sprd_clk_gate_is_enabled,
+};
+
+static void sprd_clk_sc_gate_endisable(struct clk_hw *hw, int enable,
+ unsigned int offset)
+{
+ struct clk_gate *gate = to_clk_gate(hw);
+ int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
+ unsigned long flags = 0;
+ void __iomem *reg;
+
+ set ^= enable;
+
+ sprd_clk_lock(gate, flags);
+
+ /*
+ * Each gate clock has three registers:
+ * gate->reg - base register
+ * gate->reg + offset - set register
+ * gate->reg + 2 * offset - clear register
+ */
+ reg = set ? gate->reg + offset : gate->reg + 2 * offset;
+ clk_writel(BIT(gate->bit_idx), reg);
+
+ sprd_clk_unlock(gate, flags);
+
+}
+
+static int sprd_clk_sc100_gate_enable(struct clk_hw *hw)
+{
+ sprd_clk_sc_gate_endisable(hw, 1, 0x100);
+
+ return 0;
+}
+
+static void sprd_clk_sc100_gate_disable(struct clk_hw *hw)
+{
+ sprd_clk_sc_gate_endisable(hw, 0, 0x100);
+}
+
+static int sprd_clk_sc1000_gate_enable(struct clk_hw *hw)
+{
+ sprd_clk_sc_gate_endisable(hw, 1, 0x1000);
+
+ return 0;
+}
+
+static void sprd_clk_sc1000_gate_disable(struct clk_hw *hw)
+{
+ sprd_clk_sc_gate_endisable(hw, 0, 0x1000);
+}
+
+const struct clk_ops sprd_clk_sc100_gate_ops = {
+ .enable = sprd_clk_sc100_gate_enable,
+ .disable = sprd_clk_sc100_gate_disable,
+ .is_enabled = sprd_clk_gate_is_enabled,
+};
+
+const struct clk_ops sprd_clk_sc1000_gate_ops = {
+ .enable = sprd_clk_sc1000_gate_enable,
+ .disable = sprd_clk_sc1000_gate_disable,
+ .is_enabled = sprd_clk_gate_is_enabled,
+};
+
+static struct clk *sprd_clk_register_gate(struct device *dev,
+ const char *name, const char *parent_name,
+ unsigned long flags, void __iomem *reg,
+ u8 bit_idx, u8 clk_gate_flags,
+ spinlock_t *lock, const struct clk_ops *ops)
+{
+ struct clk_gate *gate;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = ops;
+ init.flags = flags | CLK_IS_BASIC;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ gate->reg = reg;
+ gate->bit_idx = bit_idx;
+ gate->flags = clk_gate_flags;
+ gate->lock = lock;
+ gate->hw.init = &init;
+
+ clk = clk_register(dev, &gate->hw);
+
+ if (IS_ERR(clk))
+ kfree(gate);
+
+ return clk;
+}
+
+static void __init sprd_clk_gates_setup(struct device_node *node,
+ const struct clk_ops *ops)
+{
+ const char *clk_name = NULL;
+ void __iomem *reg;
+ const char *parent_name;
+ unsigned long flags = CLK_IGNORE_UNUSED;
+ u8 gate_flags = 0;
+ u32 index;
+ int number, i = 0;
+ struct resource res;
+ struct clk_onecell_data *clk_data;
+ struct property *prop;
+ const __be32 *p;
+
+ if (of_address_to_resource(node, 0, &res)) {
+ pr_err("%s: no DT registers found for %s\n",
+ __func__, node->full_name);
+ return;
+ }
+
+ /*
+ * bit[1:0] represents the gate flags, but bit[1] is not used
+ * for the time being.
+ */
+ if (res.start & 0x3) {
+ res.start &= ~0x3;
+ gate_flags |= CLK_GATE_SET_TO_DISABLE;
+ }
+ reg = ioremap(res.start, resource_size(&res));
+ if (!reg) {
+ pr_err("%s: gates clock[%s] ioremap failed!\n",
+ __func__, node->full_name);
+ return;
+ }
+
+ parent_name = of_clk_get_parent_name(node, 0);
+
+ clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
+ if (!clk_data)
+ goto iounmap_reg;
+
+ number = of_property_count_u32_elems(node, "clock-indices");
+ if (number > 0) {
+ of_property_read_u32_index(node, "clock-indices",
+ number - 1, &number);
+ number += 1;
+ } else {
+ number = of_property_count_strings(node, "clock-output-names");
+ }
+
+ clk_data->clks = kcalloc(number, sizeof(struct clk *),
+ GFP_KERNEL);
+ if (!clk_data->clks)
+ goto kfree_clk_data;
+
+ /*
+ * If the identifying number for the clocks in the node is not
+ * linear from zero, then we use clock-indices mapping
+ * identifiers into the clock-output-names array in DT.
+ */
+ if (of_property_count_u32_elems(node, "clock-indices") > 0) {
+ of_property_for_each_u32(node, "clock-indices",
+ prop, p, index) {
+ of_property_read_string_index(node,
+ "clock-output-names",
+ i++, &clk_name);
+
+ clk_data->clks[index] = sprd_clk_register_gate(NULL,
+ clk_name, parent_name, flags,
+ reg, index, gate_flags,
+ &gate_lock, ops);
+ WARN_ON(IS_ERR(clk_data->clks[index]));
+
+ clk_register_clkdev(clk_data->clks[index], clk_name,
+ NULL);
+ }
+ } else {
+ of_property_for_each_string(node, "clock-output-names",
+ prop, clk_name) {
+ clk_data->clks[i] = sprd_clk_register_gate(NULL,
+ clk_name, parent_name, flags,
+ reg, i, gate_flags,
+ &gate_lock, ops);
+ WARN_ON(IS_ERR(clk_data->clks[i]));
+
+ clk_register_clkdev(clk_data->clks[i], clk_name, NULL);
+ i++;
+ }
+ }
+
+ clk_data->clk_num = number;
+ if (number == 1)
+ of_clk_add_provider(node, of_clk_src_simple_get, clk_data);
+ else
+ of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+ return;
+
+kfree_clk_data:
+ kfree(clk_data);
+
+iounmap_reg:
+ iounmap(reg);
+}
+
+static void __init sprd_sc100_clk_gates_setup(struct device_node *node)
+{
+ sprd_clk_gates_setup(node, &sprd_clk_sc100_gate_ops);
+}
+
+static void __init sprd_sc1000_clk_gates_setup(struct device_node *node)
+{
+ sprd_clk_gates_setup(node, &sprd_clk_sc1000_gate_ops);
+}
+
+static void __init sprd_trad_clk_gates_setup(struct device_node *node)
+{
+ sprd_clk_gates_setup(node, &sprd_clk_gate_ops);
+}
+
+CLK_OF_DECLARE(gates_clock, "sprd,gates-clock",
+ sprd_trad_clk_gates_setup);
+CLK_OF_DECLARE(sc100_gates_clock, "sprd,sc100-gates-clock",
+ sprd_sc100_clk_gates_setup);
+CLK_OF_DECLARE(sc1000_gates_clock, "sprd,sc1000-gates-clock",
+ sprd_sc1000_clk_gates_setup);
+
+#ifdef CONFIG_SPRD_HWSPINLOCK
+static int __init sprd_clk_hwspinlock_init(void)
+{
+ /*
+ * glb_clk belongs to the global registers, so it can use the
+ * same hwspinlock
+ */
+ glb_clk_hw_lock = hwspin_lock_get_used(1);
+ if (!glb_clk_hw_lock) {
+ pr_err("%s: Can't get the hardware spinlock.\n", __func__);
+ return -ENXIO;
+ }
+
+ return 0;
+}
+subsys_initcall_sync(sprd_clk_hwspinlock_init);
+#endif
diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
new file mode 100644
index 0000000..118565a
--- /dev/null
+++ b/drivers/clk/sprd/composite.c
@@ -0,0 +1,109 @@
+/*
+ * Spreadtrum composite clock driver
+ *
+ * Copyright (C) 2015~2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+void __init sprd_composite_clk_setup(struct device_node *node)
+{
+ struct clk *clk;
+ struct clk_mux *mux = NULL;
+ const struct clk_ops *mux_ops = NULL;
+ struct clk_divider *div = NULL;
+ const struct clk_ops *div_ops = NULL;
+ const char *clk_name = node->name;
+ const char **parent_names;
+ unsigned long flags = 0;
+ u32 msk;
+ int num_parents = 0;
+ int i = 0;
+ int index = 0;
+
+ if (of_property_read_string(node, "clock-output-names", &clk_name))
+ return;
+
+ num_parents = of_clk_get_parent_count(node);
+ if (!num_parents) {
+ pr_err("%s: Failed to get %s's parent number!\n",
+ __func__, clk_name);
+ return;
+ }
+
+ parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL);
+ if (!parent_names)
+ return;
+
+ while (i < num_parents &&
+ (parent_names[i] =
+ of_clk_get_parent_name(node, i)) != NULL)
+ i++;
+
+ mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+ if (!mux)
+ goto kfree_parent_names;
+
+ if (!of_property_read_u32(node, "sprd,mux-msk", &msk)) {
+ mux->reg = of_iomap(node, index++);
+ if (!mux->reg)
+ goto kfree_mux;
+
+ mux->shift = __ffs(msk);
+ mux->mask = msk >> (mux->shift);
+ mux_ops = &clk_mux_ops;
+ }
+
+ div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
+ if (!div)
+ goto iounmap_mux_reg;
+
+ if (!of_property_read_u32(node, "sprd,div-msk", &msk)) {
+ div->reg = of_iomap(node, index);
+ if (!div->reg)
+ div->reg = mux->reg;
+ if (!div->reg)
+ goto iounmap_mux_reg;
+
+ div->shift = __ffs(msk);
+ div->width = fls(msk) - div->shift;
+ div_ops = &clk_divider_ops;
+ }
+
+ flags |= CLK_IGNORE_UNUSED;
+ clk = clk_register_composite(NULL, clk_name, parent_names, num_parents,
+ &mux->hw, mux_ops, &div->hw, div_ops, NULL,
+ NULL, flags);
+ if (!IS_ERR(clk)) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ return;
+ }
+
+ if (div->reg)
+ if (!mux || (div->reg != mux->reg))
+ iounmap(div->reg);
+
+ kfree(div);
+
+iounmap_mux_reg:
+ if (mux->reg)
+ iounmap(mux->reg);
+
+kfree_mux:
+ kfree(mux);
+
+kfree_parent_names:
+ pr_err("Failed to register composite clk %s!\n", clk_name);
+ kfree(parent_names);
+}
+
+CLK_OF_DECLARE(composite_clock, "sprd,composite-clock",
+ sprd_composite_clk_setup);
diff --git a/drivers/clk/sprd/divider.c b/drivers/clk/sprd/divider.c
new file mode 100644
index 0000000..785d6c4
--- /dev/null
+++ b/drivers/clk/sprd/divider.c
@@ -0,0 +1,79 @@
+/*
+ * Spreadtrum divider clock driver
+ *
+ * Copyright (C) 2015~2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+void __init sprd_divider_clk_setup(struct device_node *node)
+{
+ struct clk *clk, *pclk;
+ struct clk_divider *clk_div;
+ struct clk_composite *clk_composite;
+ const char *clk_name = node->name;
+ const char *parent;
+ void __iomem *reg;
+ u32 msk = 0;
+ u8 shift = 0;
+ u8 width = 0;
+
+ if (of_property_read_string(node, "clock-output-names", &clk_name))
+ return;
+
+ parent = of_clk_get_parent_name(node, 0);
+
+ if (of_property_read_bool(node, "reg")) {
+ reg = of_iomap(node, 0);
+ } else {
+ pclk = __clk_lookup(parent);
+ if (!pclk) {
+ pr_err("%s: clock[%s] has no reg and parent!\n",
+ __func__, clk_name);
+ return;
+ }
+
+ clk_composite = container_of(__clk_get_hw(pclk),
+ struct clk_composite, hw);
+
+ clk_div = container_of(clk_composite->rate_hw,
+ struct clk_divider, hw);
+
+ reg = clk_div->reg;
+ }
+
+ if (!reg) {
+ pr_err("%s: clock[%s] remap register failed!\n",
+ __func__, clk_name);
+ return;
+ }
+
+ if (of_property_read_u32(node, "sprd,div-msk", &msk)) {
+ pr_err("%s: Failed to get %s's div-msk\n", __func__, clk_name);
+ goto iounmap_reg;
+ }
+
+ shift = __ffs(msk);
+ width = fls(msk) - shift;
+ clk = clk_register_divider(NULL, clk_name, parent,
+ 0, reg, shift, width, 0, NULL);
+ if (!IS_ERR(clk)) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ return;
+ }
+
+iounmap_reg:
+ iounmap(reg);
+ pr_err("%s: Failed to register divider clock[%s]!\n",
+ __func__, clk_name);
+}
+
+CLK_OF_DECLARE(divider_clock, "sprd,divider-clock", sprd_divider_clk_setup);
diff --git a/drivers/clk/sprd/mux.c b/drivers/clk/sprd/mux.c
new file mode 100644
index 0000000..5969282
--- /dev/null
+++ b/drivers/clk/sprd/mux.c
@@ -0,0 +1,77 @@
+/*
+ * Spreadtrum multiplexer clock driver
+ *
+ * Copyright (C) 2015~2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+void __init sprd_mux_clk_setup(struct device_node *node)
+{
+ struct clk *clk;
+ const char *clk_name = node->name;
+ const char **parent_names;
+ int num_parents = 0;
+ void __iomem *reg;
+ u32 msk = 0;
+ u8 shift = 0;
+ u8 width = 0;
+ int i = 0;
+
+ if (of_property_read_string(node, "clock-output-names", &clk_name))
+ return;
+
+ if (of_property_read_u32(node, "sprd,mux-msk", &msk)) {
+ pr_err("%s: No mux-msk property found for %s!\n",
+ __func__, clk_name);
+ return;
+ }
+ shift = __ffs(msk);
+ width = fls(msk) - shift;
+
+ num_parents = of_clk_get_parent_count(node);
+ if (!num_parents) {
+ pr_err("%s: no parent found for %s!\n",
+ __func__, clk_name);
+ return;
+ }
+
+ parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL);
+ if (!parent_names)
+ return;
+
+ while (i < num_parents &&
+ (parent_names[i] =
+ of_clk_get_parent_name(node, i)) != NULL)
+ i++;
+
+ reg = of_iomap(node, 0);
+ if (!reg) {
+ pr_err("%s: mux-clock[%s] of_iomap failed!\n", __func__,
+ clk_name);
+ goto kfree_parent_names;
+ }
+
+ clk = clk_register_mux(NULL, clk_name, parent_names, num_parents,
+ CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+ reg, shift, width, 0, NULL);
+ if (clk) {
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ clk_register_clkdev(clk, clk_name, NULL);
+ return;
+ }
+
+ iounmap(reg);
+
+kfree_parent_names:
+ kfree(parent_names);
+}
+
+CLK_OF_DECLARE(muxed_clock, "sprd,muxed-clock", sprd_mux_clk_setup);
diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c
new file mode 100644
index 0000000..de32bce
--- /dev/null
+++ b/drivers/clk/sprd/pll.c
@@ -0,0 +1,359 @@
+/*
+ * Spreatrum pll clock driver
+ *
+ * Copyright (C) 2015~2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/delay.h>
+#include "pll_cfg.h"
+
+struct sprd_pll_config *g_sprd_pll_config;
+
+static void pll_write(void __iomem *reg, u32 val, u32 msk)
+{
+ writel_relaxed((readl_relaxed(reg) & ~msk) | val, reg);
+}
+
+static unsigned long pll_get_refin_rate(struct sprd_pll_hw *pll,
+ struct sprd_pll_config *ppll_config)
+{
+ u32 i = 3;
+ u8 index;
+ u32 value;
+ const unsigned long refin[4] = { 2, 4, 13, 26 };
+
+ value = ppll_config->refin_msk.value;
+ index = ppll_config->refin_msk.index;
+ if (value) {
+ i = (readl_relaxed(pll->reg[index]) & value) >> __ffs(value);
+ i = i > 3 ? 3 : i;
+ }
+
+ return refin[i];
+}
+
+static u8 pll_get_ibias(unsigned long rate, struct pll_ibias_table *table)
+{
+ if (!table)
+ return 0;
+
+ for (; table->rate < SPRD_PLL_MAX_RATE; table++)
+ if (rate <= table->rate)
+ break;
+
+ return table->ibias;
+}
+
+static void *pll_get_config(struct clk_hw *hw,
+ struct sprd_pll_config *pll_config)
+{
+ struct sprd_pll_config *p;
+
+ for (p = pll_config; p->name != NULL; p++)
+ if (!strcmp(p->name, __clk_get_name(hw->clk)))
+ break;
+
+ return p->name ? p : NULL;
+}
+
+static int pll_clk_prepare(struct clk_hw *hw)
+{
+ struct sprd_pll_config *pcfg;
+
+ pcfg = pll_get_config(hw, g_sprd_pll_config);
+ if (!pcfg)
+ return -EPERM;
+
+ udelay(pcfg->udelay);
+
+ return 0;
+}
+
+static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ return rate;
+}
+
+static inline int pll_check(struct sprd_pll_hw *pll,
+ struct sprd_pll_config *ppll_config)
+{
+ if ((ppll_config->lock_done.index >= pll->reg_num) ||
+ (ppll_config->div_s.index >= pll->reg_num) ||
+ (ppll_config->mod_en.index >= pll->reg_num) ||
+ (ppll_config->sdm_en.index >= pll->reg_num) ||
+ (ppll_config->refin_msk.index >= pll->reg_num) ||
+ (ppll_config->ibias_msk.index >= pll->reg_num) ||
+ (ppll_config->pll_n_msk.index >= pll->reg_num) ||
+ (ppll_config->nint_msk.index >= pll->reg_num) ||
+ (ppll_config->kint_msk.index >= pll->reg_num) ||
+ (ppll_config->prediv_msk.index >= pll->reg_num)) {
+ pr_err("%s: pll[%s] exceed max:%d\n", __func__,
+ __clk_get_name(pll->hw.clk), pll->reg_num);
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* get field */
+#define gf(array, pll_struct) \
+ (array[pll_struct.index] & pll_struct.value)
+
+/* get field value */
+#define gfv(array, pll_struct) \
+ (gf(array, pll_struct) >> __ffs(pll_struct.value))
+
+static unsigned long pll_recalc_rate(struct sprd_pll_hw *pll,
+ struct sprd_pll_config *ppll_config,
+ unsigned long parent_rate)
+{
+ unsigned long rate, refin, k1, k2;
+ unsigned long kint = 0, nint, cfg[SPRD_PLL_MAX_REGNUM], n;
+ int i;
+ u32 value;
+
+ if (!ppll_config) {
+ pr_err("%s:%d Cannot get pll %s\n", __func__,
+ __LINE__, __clk_get_name(pll->hw.clk));
+ return parent_rate;
+ }
+
+ if (pll_check(pll, ppll_config))
+ return parent_rate;
+
+ for (i = 0; i < pll->reg_num; i++)
+ cfg[i] = readl_relaxed(pll->reg[i]);
+
+ refin = pll_get_refin_rate(pll, ppll_config);
+
+ if (gf(cfg, ppll_config->prediv_msk))
+ refin = refin * 2;
+
+ if (ppll_config->postdiv_msk.value &&
+ (((ppll_config->postdiv_msk.fvco_threshold->flag == 1) &&
+ gf(cfg, ppll_config->postdiv_msk)) ||
+ ((ppll_config->postdiv_msk.fvco_threshold->flag == 0) &&
+ !gf(cfg, ppll_config->postdiv_msk))))
+ refin = refin / 2;
+
+ if (!gf(cfg, ppll_config->div_s)) {
+ n = gfv(cfg, ppll_config->pll_n_msk);
+ rate = refin * n * 10000000;
+ } else {
+ nint = gfv(cfg, ppll_config->nint_msk);
+ if (gf(cfg, ppll_config->sdm_en))
+ kint = gfv(cfg, ppll_config->kint_msk);
+
+ value = ppll_config->kint_msk.value;
+#ifdef CONFIG_64BIT
+ k1 = 1000;
+ k2 = 1000;
+ i = 0;
+#else
+ k1 = 100;
+ k2 = 10000;
+ i = fls(value >> __ffs(value));
+ i = i < 20 ? 0 : i - 20;
+#endif
+ rate = DIV_ROUND_CLOSEST(refin * (kint >> i) * k1,
+ ((value >> (__ffs(value) + i)) + 1)) *
+ k2 + refin * nint * 1000000;
+ }
+
+ return rate;
+}
+
+static int pll_adjustable_set_rate(struct sprd_pll_hw *pll,
+ struct sprd_pll_config *ppll_config,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ u8 ibias, index;
+ u32 value;
+ unsigned long kint, nint;
+ unsigned long refin, val, fvco = rate;
+ struct reg_cfg cfg[SPRD_PLL_MAX_REGNUM] = {{},};
+ struct fvco_threshold *ft;
+ int i = 0;
+
+ if (ppll_config == NULL) {
+ pr_err("%s:%d Cannot get pll clk[%s]\n", __func__,
+ __LINE__, __clk_get_name(pll->hw.clk));
+ return -EINVAL;
+ }
+
+ if (pll_check(pll, ppll_config))
+ return -EINVAL;
+
+ /* calc the pll refin */
+ refin = pll_get_refin_rate(pll, ppll_config);
+
+ value = ppll_config->prediv_msk.value;
+ index = ppll_config->prediv_msk.index;
+ if (value) {
+ val = readl_relaxed(pll->reg[index]);
+ if (val & value)
+ refin = refin * 2;
+ }
+
+ value = ppll_config->postdiv_msk.value;
+ index = ppll_config->postdiv_msk.index;
+ ft = ppll_config->postdiv_msk.fvco_threshold;
+ cfg[index].msk = value;
+ if (value && ((ft->flag == 1 && fvco <= ft->rate) ||
+ (ft->flag == 0 && fvco > ft->rate)))
+ cfg[index].val |= value;
+
+ if (fvco <= ft->rate)
+ fvco = fvco * 2;
+
+ value = ppll_config->div_s.value;
+ index = ppll_config->div_s.index;
+ cfg[index].val |= value;
+ cfg[index].msk |= value;
+
+ value = ppll_config->sdm_en.value;
+ index = ppll_config->sdm_en.index;
+ cfg[index].val |= value;
+ cfg[index].msk |= value;
+
+ nint = fvco/(refin * 1000000);
+
+ value = ppll_config->nint_msk.value;
+ index = ppll_config->nint_msk.index;
+ cfg[index].val |= (nint << __ffs(value)) & value;
+ cfg[index].msk |= value;
+
+ value = ppll_config->kint_msk.value;
+ index = ppll_config->kint_msk.index;
+#ifndef CONFIG_64BIT
+ i = fls(value >> __ffs(value));
+ i = i < 20 ? 0 : i - 20;
+#endif
+ kint = DIV_ROUND_CLOSEST(((fvco - refin * nint * 1000000)/10000) *
+ ((value >> (__ffs(value) + i)) + 1), refin * 100) << i;
+ cfg[index].val |= (kint << __ffs(value)) & value;
+ cfg[index].msk |= value;
+
+ ibias = pll_get_ibias(fvco, ppll_config->itable);
+ value = ppll_config->ibias_msk.value;
+ index = ppll_config->ibias_msk.index;
+ cfg[index].val |= ibias << __ffs(value) & value;
+ cfg[index].msk |= value;
+
+ for (i = 0; i < pll->reg_num; i++)
+ if (cfg[i].msk)
+ pll_write(pll->reg[i], cfg[i].val, cfg[i].msk);
+
+ udelay(ppll_config->udelay);
+
+ return 0;
+}
+
+static void pll_clk_setup(struct device_node *node,
+ const struct clk_ops *clk_ops)
+{
+ struct clk *clk = NULL;
+ const char *parent_names;
+ struct sprd_pll_hw *pll;
+ int reg_num, index;
+ struct clk_init_data init = {
+ .ops = clk_ops,
+ .flags = CLK_IGNORE_UNUSED,
+ .num_parents = 1,
+ };
+
+ parent_names = of_clk_get_parent_name(node, 0);
+ if (!parent_names) {
+ pr_err("%s: Failed to get parent_names in node[%s]\n",
+ __func__, node->name);
+ return;
+ }
+ init.parent_names = &parent_names;
+
+ if (of_property_read_string(node, "clock-output-names", &init.name))
+ return;
+
+ pll = kzalloc(sizeof(struct sprd_pll_hw), GFP_KERNEL);
+ if (!pll)
+ return;
+
+ reg_num = of_property_count_u32_elems(node, "reg");
+ reg_num = reg_num / (of_n_addr_cells(node) + of_n_size_cells(node));
+ if (reg_num > SPRD_PLL_MAX_REGNUM) {
+ pr_err("%s: reg_num:%d exceed max number\n",
+ __func__, reg_num);
+ goto kfree_pll;
+ }
+ pll->reg_num = reg_num;
+
+ for (index = 0; index < reg_num; index++) {
+ pll->reg[index] = of_iomap(node, index);
+ if (!pll->reg[index])
+ goto kfree_pll;
+ }
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (!IS_ERR(clk)) {
+ clk_register_clkdev(clk, init.name, 0);
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ return;
+ }
+
+kfree_pll:
+ kfree(pll);
+}
+
+static unsigned long sprd_adjustable_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct sprd_pll_config *ppll_config;
+ struct sprd_pll_hw *pll = to_sprd_pll_hw(hw);
+
+ ppll_config = pll_get_config(hw, g_sprd_pll_config);
+
+ return pll_recalc_rate(pll, ppll_config, parent_rate);
+}
+
+static int sprd_adjustable_pll_set_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct sprd_pll_config *ppll_config;
+ struct sprd_pll_hw *pll = to_sprd_pll_hw(hw);
+
+ ppll_config = pll_get_config(hw, g_sprd_pll_config);
+
+ return pll_adjustable_set_rate(pll, ppll_config, rate,
+ parent_rate);
+}
+
+const struct clk_ops sprd_adjustable_pll_ops = {
+ .prepare = pll_clk_prepare,
+ .round_rate = pll_round_rate,
+ .set_rate = sprd_adjustable_pll_set_rate,
+ .recalc_rate = sprd_adjustable_pll_recalc_rate,
+};
+
+static void __init sc9836_adjustable_pll_setup(struct device_node *node)
+{
+ g_sprd_pll_config = sc9836_pll_config;
+ pll_clk_setup(node, &sprd_adjustable_pll_ops);
+}
+
+static void __init sc9860_adjustable_pll_setup(struct device_node *node)
+{
+ g_sprd_pll_config = sc9860_pll_config;
+ pll_clk_setup(node, &sprd_adjustable_pll_ops);
+}
+
+CLK_OF_DECLARE(sc9836_adjustable_pll_clock, "sprd,sc9836-adjustable-pll-clock",
+ sc9836_adjustable_pll_setup);
+CLK_OF_DECLARE(sc9860_adjustable_pll_clock, "sprd,sc9860-adjustable-pll-clock",
+ sc9860_adjustable_pll_setup);
diff --git a/drivers/clk/sprd/pll.h b/drivers/clk/sprd/pll.h
new file mode 100644
index 0000000..4b79092
--- /dev/null
+++ b/drivers/clk/sprd/pll.h
@@ -0,0 +1,73 @@
+/*
+ * Spreatrum clock pll driver head file
+ *
+ * Copyright (C) 2015~2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __SPRD_PLL_H__
+#define __SPRD_PLL_H__
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#define SPRD_PLL_MAX_RATE ULONG_MAX
+#define SPRD_PLL_MAX_REGNUM (3)
+#define SPRD_DELAY_200 (200)
+#define SPRD_DELAY_1000 (1000)
+
+struct reg_cfg {
+ u32 val;
+ u32 msk;
+};
+
+struct pll_common {
+ u32 value;
+ u8 index;
+};
+
+struct fvco_threshold {
+ unsigned long rate;
+ int flag;
+};
+
+struct pll_div_mask {
+ u32 value;
+ u8 index;
+ struct fvco_threshold *fvco_threshold;
+};
+
+struct pll_ibias_table {
+ unsigned long rate;
+ u8 ibias;
+};
+
+struct sprd_pll_config {
+ char *name;
+ u32 udelay;
+ struct pll_common lock_done;
+ struct pll_common div_s;
+ struct pll_common mod_en;
+ struct pll_common sdm_en;
+ struct pll_common refin_msk;
+ struct pll_common ibias_msk;
+ struct pll_common pll_n_msk;
+ struct pll_common nint_msk;
+ struct pll_common kint_msk;
+ struct pll_div_mask prediv_msk;
+ struct pll_div_mask postdiv_msk;
+ struct pll_ibias_table *itable;
+};
+
+struct sprd_pll_hw {
+ struct clk_hw hw;
+ void __iomem *reg[SPRD_PLL_MAX_REGNUM];
+ int reg_num;
+};
+
+#define to_sprd_pll_hw(_hw) container_of(_hw, struct sprd_pll_hw, hw)
+
+#endif
diff --git a/drivers/clk/sprd/pll_cfg.h b/drivers/clk/sprd/pll_cfg.h
new file mode 100644
index 0000000..64e79f3
--- /dev/null
+++ b/drivers/clk/sprd/pll_cfg.h
@@ -0,0 +1,390 @@
+/*
+ * Spreatrum clock pll configurations
+ *
+ * Copyright (C) 2015~2017 Spreadtrum, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __SPRD_PLL_CFG_H__
+#define __SPRD_PLL_CFG_H__
+
+#include "pll.h"
+
+static struct sprd_pll_config sc9836_pll_config[] = {
+ {
+ .name = "sc9836_pll",
+ .udelay = SPRD_DELAY_1000,
+ .lock_done.value = 1 << 27,
+ .lock_done.index = 0,
+ .div_s.value = 1 << 26,
+ .div_s.index = 0,
+ .mod_en.value = 1 << 25,
+ .mod_en.index = 0,
+ .sdm_en.value = 1 << 24,
+ .sdm_en.index = 0,
+ .refin_msk.value = 3 << 18,
+ .refin_msk.index = 0,
+ .ibias_msk.value = 3 << 16,
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7ff,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = 0x3f << 24,
+ .nint_msk.index = 1,
+ .kint_msk.value = 0xfffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0,
+ .prediv_msk.index = 0,
+ .postdiv_msk.value = 0x0,
+ .itable = NULL,
+ },
+
+ /* add configures above this */
+ {
+ .name = NULL,
+ }
+};
+
+/* GPLL/LPLL/DPLL/RPLL/CPLL */
+static struct pll_ibias_table sc9860_adjustable_pll1_table[] = {
+ {
+ .rate = 780000000,
+ .ibias = 0x0,
+ },
+ {
+ .rate = 988000000,
+ .ibias = 0x1,
+ },
+ {
+ .rate = 1196000000,
+ .ibias = 0x2,
+ },
+
+ /* add items above this */
+ {
+ .rate = SPRD_PLL_MAX_RATE,
+ .ibias = 0x2,
+ },
+};
+
+/* TWPLL/MPLL0/MPLL1 */
+static struct pll_ibias_table sc9860_adjustable_pll2_table[] = {
+ {
+ .rate = 1638000000,
+ .ibias = 0x0,
+ },
+ {
+ .rate = 2080000000,
+ .ibias = 0x1,
+ },
+ {
+ .rate = 2600000000UL,
+ .ibias = 0x2,
+ },
+
+ /* add items above this */
+ {
+ .rate = SPRD_PLL_MAX_RATE,
+ .ibias = 0x2,
+ },
+};
+
+static struct fvco_threshold sc9860_mpll0_threshold = {
+ .rate = 1300000000,
+ .flag = 1,
+};
+
+static struct fvco_threshold sc9860_gpll_threshold = {
+ .rate = 600000000,
+ .flag = 1,
+};
+
+static struct sprd_pll_config sc9860_pll_config[] = {
+ {
+ .name = "clk_mpll0",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 20),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 19),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 18),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 17),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 11),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = (0x7f),
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = (1 << 24),
+ .postdiv_msk.index = 1,
+ .postdiv_msk.fvco_threshold = &sc9860_mpll0_threshold,
+ .itable = sc9860_adjustable_pll2_table,
+ },
+ {
+ .name = "clk_mpll1",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 20),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 19),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 18),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 17),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 11),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7f,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = (1 << 24),
+ .prediv_msk.index = 1,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll2_table,
+ },
+ {
+ .name = "clk_gpll",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 18),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 15),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 14),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 13),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 8),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7f,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.fvco_threshold = &sc9860_gpll_threshold,
+ .postdiv_msk.value = (1 << 17),
+ .postdiv_msk.index = 0,
+ .itable = sc9860_adjustable_pll1_table,
+ },
+ {
+ .name = "clk_dpll0",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 16),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 15),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 14),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 13),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 8),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7f,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll1_table,
+ },
+ {
+ .name = "clk_dpll1",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 16),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 15),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 14),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 13),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 8),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7f,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll1_table,
+ },
+ {
+ .name = "clk_twpll",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 21),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 20),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 19),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 18),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 13),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7f,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll2_table,
+ },
+ {
+ .name = "clk_ltepll0",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 31),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 27),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 26),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 25),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 20),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7f,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll1_table,
+ },
+ {
+ .name = "clk_ltepll1",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 31),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 27),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 26),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 25),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 20),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7f,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll1_table,
+ },
+ {
+ .name = "clk_cppll",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 17),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 15),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 14),
+ .mod_en.index = 0,
+ .sdm_en.value = (1 << 13),
+ .sdm_en.index = 0,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 8),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = 0x7f,
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 25),
+ .nint_msk.index = 1,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll1_table,
+ },
+ {
+ /* rpll register bit is different from other plls. */
+ .name = "clk_rpll0",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 0),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 3),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 16),
+ .mod_en.index = 2,
+ .sdm_en.value = (1 << 17),
+ .sdm_en.index = 2,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 14),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = (0x7f << 16),
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 4),
+ .nint_msk.index = 0,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll1_table,
+ },
+ {
+ .name = "clk_rpll1",
+ .udelay = SPRD_DELAY_200,
+ .lock_done.value = (1 << 0),
+ .lock_done.index = 0,
+ .div_s.value = (1 << 3),
+ .div_s.index = 0,
+ .mod_en.value = (1 << 16),
+ .mod_en.index = 2,
+ .sdm_en.value = (1 << 17),
+ .sdm_en.index = 2,
+ .refin_msk.value = 0,
+ .refin_msk.index = 0,
+ .ibias_msk.value = (3 << 14),
+ .ibias_msk.index = 0,
+ .pll_n_msk.value = (0x7f << 16),
+ .pll_n_msk.index = 0,
+ .nint_msk.value = (0x7f << 4),
+ .nint_msk.index = 0,
+ .kint_msk.value = 0x7fffff,
+ .kint_msk.index = 1,
+ .prediv_msk.value = 0x0,
+ .postdiv_msk.value = 0x0,
+ .itable = sc9860_adjustable_pll1_table,
+ },
+
+ /* add configures above this */
+ {
+ .name = NULL,
+ }
+};
+#endif
--
2.7.4
^ permalink raw reply related [flat|nested] 8+ messages in thread