1 | The clock tree of SpacemiT K1 is managed by several independent | 1 | The clock tree of SpacemiT K1 is managed by several independent |
---|---|---|---|
2 | controllers in different SoC parts. In this series, all clock hardwares | 2 | multifunction devices, some of them are |
3 | in APBS, MPMU, APBC and APMU are implemented. Clocks in other SoC parts | 3 | |
4 | could be implemented later. | 4 | - Application Power Manage Unit, APMU |
5 | 5 | - Main Power Manage Unit, MPMU | |
6 | This driver has been tested on BananaPi-F3 board. With some out-of-tree | 6 | - APB Bus Clock Unit, APBC |
7 | drivers, I've successfully brought up I2C, RTC, MMC and ethernet | 7 | - APB Spare, APBS |
8 | controllers, proving it works. A clock tree dump could be obtained | 8 | |
9 | here[1]. | 9 | These four devices provide hardware bits for three purposes: power |
10 | 10 | management, reset signals and clocks. Not every device is capable of all | |
11 | [1]: https://gist.github.com/heylenayy/fda51ac6736ac97a2c53d8caa3302378 | 11 | the three functionalities, |
12 | 12 | ||
13 | Link: https://developer.spacemit.com/documentation?token=LCrKwWDasiJuROkVNusc2pWTnEb | 13 | - APMU, MPMU: power, reset, clock |
14 | - APBC: clock, reset | ||
15 | - APBS: clock (PLL clocks) | ||
16 | |||
17 | This series adds support for clock hardwares in these four regions, | ||
18 | which covers most peripherals except DDR and the realtime processor. | ||
19 | |||
20 | Tested on BananaPi-F3 board. With some out-of-tree drivers, I've | ||
21 | successfully brought up I2C, RTC, MMC and ethernet controllers. A clock | ||
22 | tree dump could be obtained here[1]. | ||
23 | |||
24 | [1]: https://gist.github.com/heylenayy/73df0b6b075615a944990507112cfc5b | ||
25 | |||
26 | Changed from v5 | ||
27 | - Correct "Spacemit" to "SpacemiT" in commit messages and code | ||
28 | - Always use space instead of TAB in comments for consistency | ||
29 | - dt-bindings | ||
30 | - Rename binding header to "spacemit,k1-syscon.h" | ||
31 | - apply review tags | ||
32 | - driver code | ||
33 | - remove "default" properties from Kconfig | ||
34 | - misc style and naming improvements | ||
35 | - make ccu_read() directly return the read value, drop ccu_poll() and | ||
36 | reorder the arguments to ccu_{read,update} macros | ||
37 | - drop ccu_common.reg_swcr2 | ||
38 | - clock tree for K1 | ||
39 | - define PLL3 with the correct offset of SWCR3 register | ||
40 | - synchronize PLL configuration entries with the vendor kernel | ||
41 | - reformat clocks definitions | ||
42 | - explain why PLLs require the MPMU syscon to function | ||
43 | - log a message when failing to register a clock | ||
44 | - simplify clock registration with ARRAY_SIZE() | ||
45 | - ddn | ||
46 | - correctly handle masks which doesn't start from BIT(0) when | ||
47 | calculating the best rate | ||
48 | - improve precision of frequency calculation | ||
49 | - derive _{den,num}_shift from corresponding masks with __ffs() | ||
50 | - mix | ||
51 | - match the full mask of gate in ccu_gate_is_enabled() | ||
52 | - add a note about "frequency change" bit and simplify FC-triggering | ||
53 | logic | ||
54 | - drop unnecessary local variables and initialization from clock | ||
55 | operations | ||
56 | - round to the closest rate in ccu_mix_calc_best_rate() | ||
57 | - change names of all mix subtypes to follow the order of mux -> | ||
58 | factor/div -> gate -> fc | ||
59 | - drop unused _flags argument from CCU_GATE_FACTOR_DEFINE() | ||
60 | - pll | ||
61 | - ensure PLLs are initialized to a known state | ||
62 | - drop extra check in ccu_pll_enable() | ||
63 | - round to the closest rate in ccu_pll_round_rate() | ||
64 | - TWSI8 support | ||
65 | - Split cleanly from the main driver commit | ||
66 | - devicetree | ||
67 | - drop extra "*-cells" and "ranges" properties | ||
68 | - Enable SpacemiT K1 CCU in RISC-V defconfig | ||
69 | - Link to v5: https://lore.kernel.org/all/20250306175750.22480-2-heylenay@4d2.org/ | ||
70 | |||
71 | Changed from v4 | ||
72 | - bindings: | ||
73 | - Drop CLK_*_NUM macros from binding headers | ||
74 | - Rename spacemit,k1-ccu.yaml to spacemit,k1-pll.yaml, change to | ||
75 | describe only the PLL in APBS region | ||
76 | - k1-syscon.yaml | ||
77 | - drop spacemit,k1-syscon-apbs, it should be the PLL device | ||
78 | - drop child nodes | ||
79 | - describe the syscons as clock, reset and power-domain controllers | ||
80 | - drop "syscon" from the compatible list, as these syscons aren't | ||
81 | compatible with the generic one | ||
82 | - driver: | ||
83 | - misc style fixes and naming improvements | ||
84 | - drop unused fields from data structures | ||
85 | - drop unused clock types: CCU_DDN_GATE | ||
86 | - ddn type: | ||
87 | - improve the comments | ||
88 | - dynamically calculate appropriate rates | ||
89 | - hardcode the x2 factor | ||
90 | - mix type | ||
91 | - drop val_{disable,enable} for gate subtype | ||
92 | - drop unncessary polling when enabling a gate | ||
93 | - encode subtypes directly in struct ccu_mix | ||
94 | - generate clock names from identifiers of the data structure | ||
95 | - rename CCU_DIV2_FC_MUX_GATE_DEFINE to CCU_DIV_SPLIT_FC_MUX_GATE | ||
96 | - pll type: | ||
97 | - correctly claim the parent clock | ||
98 | - make rate tables const | ||
99 | - drop SWCR2-related fields | ||
100 | - combine fields of registers as a whole instead of working with | ||
101 | each field | ||
102 | - clock tree for k1: | ||
103 | - removed duplicated offsets | ||
104 | - drop the placeholder 1:1 factor, pll1_d7_351p8 | ||
105 | - workaround the quirk of TWSI8 clocks | ||
106 | - fix the definition of ripc_clk, wdt_bus_clk, dpu_bit_clk and | ||
107 | timers_*_clk | ||
108 | - drop structure spacemit_ccu_priv and spacemit_ccu_data | ||
109 | - rework clock registration | ||
110 | - split the PCIe clocks correctly (there're three distinct clocks | ||
111 | for each PCIe port) | ||
112 | - devicetree: | ||
113 | - adapt the new binding | ||
114 | - Link to v4: https://lore.kernel.org/all/20250103215636.19967-2-heylenay@4d2.org/ | ||
14 | 115 | ||
15 | Changed from v3 | 116 | Changed from v3 |
16 | - spacemit,k1-ccu binding | 117 | - spacemit,k1-ccu binding |
17 | - allow spacemit,mpmu property only for controllers requiring it | 118 | - allow spacemit,mpmu property only for controllers requiring it |
18 | (spacemit,k1-ccu-apbs) | 119 | (spacemit,k1-ccu-apbs) |
... | ... | ||
55 | - document spacemit,k1-syscon | 156 | - document spacemit,k1-syscon |
56 | - implement all APBS, MPMU, APBC and APMU clocks | 157 | - implement all APBS, MPMU, APBC and APMU clocks |
57 | - code cleanup | 158 | - code cleanup |
58 | - Link to v1: https://lore.kernel.org/all/SEYPR01MB4221B3178F5233EAB5149E41D7902@SEYPR01MB4221.apcprd01.prod.exchangelabs.com/ | 159 | - Link to v1: https://lore.kernel.org/all/SEYPR01MB4221B3178F5233EAB5149E41D7902@SEYPR01MB4221.apcprd01.prod.exchangelabs.com/ |
59 | 160 | ||
60 | Haylen Chu (4): | 161 | Haylen Chu (6): |
61 | dt-bindings: clock: spacemit: Add clock controllers of Spacemit K1 SoC | ||
62 | dt-bindings: soc: spacemit: Add spacemit,k1-syscon | 162 | dt-bindings: soc: spacemit: Add spacemit,k1-syscon |
63 | clk: spacemit: Add clock support for Spacemit K1 SoC | 163 | dt-bindings: clock: spacemit: Add spacemit,k1-pll |
64 | riscv: dts: spacemit: Add clock controller for K1 | 164 | clk: spacemit: Add clock support for SpacemiT K1 SoC |
65 | 165 | clk: spacemit: k1: Add TWSI8 bus and function clocks | |
66 | .../bindings/clock/spacemit,k1-ccu.yaml | 60 + | 166 | riscv: dts: spacemit: Add clock tree for SpacemiT K1 |
67 | .../soc/spacemit/spacemit,k1-syscon.yaml | 52 + | 167 | riscv: defconfig: enable clock controller unit support for SpacemiT K1 |
68 | arch/riscv/boot/dts/spacemit/k1.dtsi | 97 + | 168 | |
169 | .../bindings/clock/spacemit,k1-pll.yaml | 50 + | ||
170 | .../soc/spacemit/spacemit,k1-syscon.yaml | 80 + | ||
171 | arch/riscv/boot/dts/spacemit/k1.dtsi | 75 + | ||
172 | arch/riscv/configs/defconfig | 2 + | ||
69 | drivers/clk/Kconfig | 1 + | 173 | drivers/clk/Kconfig | 1 + |
70 | drivers/clk/Makefile | 1 + | 174 | drivers/clk/Makefile | 1 + |
71 | drivers/clk/spacemit/Kconfig | 20 + | 175 | drivers/clk/spacemit/Kconfig | 18 + |
72 | drivers/clk/spacemit/Makefile | 5 + | 176 | drivers/clk/spacemit/Makefile | 5 + |
73 | drivers/clk/spacemit/ccu-k1.c | 1747 +++++++++++++++++ | 177 | drivers/clk/spacemit/apbc_clks | 100 ++ |
74 | drivers/clk/spacemit/ccu_common.h | 51 + | 178 | drivers/clk/spacemit/ccu-k1.c | 1321 +++++++++++++++++ |
75 | drivers/clk/spacemit/ccu_ddn.c | 140 ++ | 179 | drivers/clk/spacemit/ccu_common.h | 48 + |
76 | drivers/clk/spacemit/ccu_ddn.h | 84 + | 180 | drivers/clk/spacemit/ccu_ddn.c | 83 ++ |
77 | drivers/clk/spacemit/ccu_mix.c | 304 +++ | 181 | drivers/clk/spacemit/ccu_ddn.h | 47 + |
78 | drivers/clk/spacemit/ccu_mix.h | 309 +++ | 182 | drivers/clk/spacemit/ccu_mix.c | 268 ++++ |
79 | drivers/clk/spacemit/ccu_pll.c | 189 ++ | 183 | drivers/clk/spacemit/ccu_mix.h | 218 +++ |
80 | drivers/clk/spacemit/ccu_pll.h | 80 + | 184 | drivers/clk/spacemit/ccu_pll.c | 157 ++ |
81 | include/dt-bindings/clock/spacemit,k1-ccu.h | 246 +++ | 185 | drivers/clk/spacemit/ccu_pll.h | 86 ++ |
82 | 16 files changed, 3386 insertions(+) | 186 | .../dt-bindings/clock/spacemit,k1-syscon.h | 247 +++ |
83 | create mode 100644 Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml | 187 | 18 files changed, 2807 insertions(+) |
188 | create mode 100644 Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml | ||
84 | create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml | 189 | create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml |
85 | create mode 100644 drivers/clk/spacemit/Kconfig | 190 | create mode 100644 drivers/clk/spacemit/Kconfig |
86 | create mode 100644 drivers/clk/spacemit/Makefile | 191 | create mode 100644 drivers/clk/spacemit/Makefile |
192 | create mode 100644 drivers/clk/spacemit/apbc_clks | ||
87 | create mode 100644 drivers/clk/spacemit/ccu-k1.c | 193 | create mode 100644 drivers/clk/spacemit/ccu-k1.c |
88 | create mode 100644 drivers/clk/spacemit/ccu_common.h | 194 | create mode 100644 drivers/clk/spacemit/ccu_common.h |
89 | create mode 100644 drivers/clk/spacemit/ccu_ddn.c | 195 | create mode 100644 drivers/clk/spacemit/ccu_ddn.c |
90 | create mode 100644 drivers/clk/spacemit/ccu_ddn.h | 196 | create mode 100644 drivers/clk/spacemit/ccu_ddn.h |
91 | create mode 100644 drivers/clk/spacemit/ccu_mix.c | 197 | create mode 100644 drivers/clk/spacemit/ccu_mix.c |
92 | create mode 100644 drivers/clk/spacemit/ccu_mix.h | 198 | create mode 100644 drivers/clk/spacemit/ccu_mix.h |
93 | create mode 100644 drivers/clk/spacemit/ccu_pll.c | 199 | create mode 100644 drivers/clk/spacemit/ccu_pll.c |
94 | create mode 100644 drivers/clk/spacemit/ccu_pll.h | 200 | create mode 100644 drivers/clk/spacemit/ccu_pll.h |
95 | create mode 100644 include/dt-bindings/clock/spacemit,k1-ccu.h | 201 | create mode 100644 include/dt-bindings/clock/spacemit,k1-syscon.h |
96 | 202 | ||
97 | |||
98 | base-commit: 2d5404caa8c7bb5c4e0435f94b28834ae5456623 | ||
99 | prerequisite-patch-id: 47dcf6861f7d434d25855b379e6d7ef4ce369c9c | ||
100 | prerequisite-patch-id: 77787fe82911923aff15ccf565e8fa451538c3a6 | ||
101 | prerequisite-patch-id: b0bdb1742d96c5738f05262c3b0059102761390b | ||
102 | prerequisite-patch-id: 3927d39d8d77e35d5bfe53d9950da574ff8f2054 | ||
103 | prerequisite-patch-id: a98039136a4796252a6029e474f03906f2541643 | ||
104 | prerequisite-patch-id: c95f6dc0547a2a63a76e3cba0cf5c623b212b4e6 | ||
105 | prerequisite-patch-id: 66e750e438ee959ddc2a6f0650814a2d8c989139 | ||
106 | prerequisite-patch-id: 29a0fd8c36c1a4340f0d0b68a4c34d2b8abfb1ab | ||
107 | prerequisite-patch-id: 0bdfff661c33c380d1cf00a6c68688e05f88c0b3 | ||
108 | prerequisite-patch-id: 99f15718e0bfbb7ed1a96dfa19f35841b004dae9 | ||
109 | -- | 203 | -- |
110 | 2.47.1 | 204 | 2.49.0 | diff view generated by jsdifflib |
1 | Add definition for the clock controllers of Spacemit K1 SoC. The clock | 1 | Document APMU, MPMU and APBC syscons found on SpacemiT K1 SoC, which are |
---|---|---|---|
2 | tree is managed by several SoC parts thus different compatible strings | 2 | capable of generating clock and reset signals. Additionally, APMU and MPMU |
3 | are introduced for each. | 3 | manage power domains. |
4 | 4 | ||
5 | Signed-off-by: Haylen Chu <heylenay@4d2.org> | 5 | Signed-off-by: Haylen Chu <heylenay@4d2.org> |
6 | Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | ||
6 | --- | 7 | --- |
7 | .../bindings/clock/spacemit,k1-ccu.yaml | 60 +++++ | 8 | .../soc/spacemit/spacemit,k1-syscon.yaml | 80 +++++++ |
8 | include/dt-bindings/clock/spacemit,k1-ccu.h | 246 ++++++++++++++++++ | 9 | .../dt-bindings/clock/spacemit,k1-syscon.h | 210 ++++++++++++++++++ |
9 | 2 files changed, 306 insertions(+) | 10 | 2 files changed, 290 insertions(+) |
10 | create mode 100644 Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml | 11 | create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml |
11 | create mode 100644 include/dt-bindings/clock/spacemit,k1-ccu.h | 12 | create mode 100644 include/dt-bindings/clock/spacemit,k1-syscon.h |
12 | 13 | ||
13 | diff --git a/Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml b/Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml | 14 | diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml |
14 | new file mode 100644 | 15 | new file mode 100644 |
15 | index XXXXXXX..XXXXXXX | 16 | index XXXXXXX..XXXXXXX |
16 | --- /dev/null | 17 | --- /dev/null |
17 | +++ b/Documentation/devicetree/bindings/clock/spacemit,k1-ccu.yaml | 18 | +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml |
18 | @@ -XXX,XX +XXX,XX @@ | 19 | @@ -XXX,XX +XXX,XX @@ |
19 | +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | 20 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
20 | +%YAML 1.2 | 21 | +%YAML 1.2 |
21 | +--- | 22 | +--- |
22 | +$id: http://devicetree.org/schemas/clock/spacemit,k1-ccu.yaml# | 23 | +$id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml# |
23 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | 24 | +$schema: http://devicetree.org/meta-schemas/core.yaml# |
24 | + | 25 | + |
25 | +title: Spacemit K1 SoC Clock Controller | 26 | +title: SpacemiT K1 SoC System Controller |
26 | + | 27 | + |
27 | +maintainers: | 28 | +maintainers: |
28 | + - Haylen Chu <heylenay@4d2.org> | 29 | + - Haylen Chu <heylenay@4d2.org> |
30 | + | ||
31 | +description: | ||
32 | + System controllers found on SpacemiT K1 SoC, which are capable of | ||
33 | + clock, reset and power-management functions. | ||
29 | + | 34 | + |
30 | +properties: | 35 | +properties: |
31 | + compatible: | 36 | + compatible: |
32 | + enum: | 37 | + enum: |
33 | + - spacemit,k1-ccu-apbs | 38 | + - spacemit,k1-syscon-apbc |
34 | + - spacemit,k1-ccu-mpmu | 39 | + - spacemit,k1-syscon-apmu |
35 | + - spacemit,k1-ccu-apbc | 40 | + - spacemit,k1-syscon-mpmu |
36 | + - spacemit,k1-ccu-apmu | 41 | + |
42 | + reg: | ||
43 | + maxItems: 1 | ||
37 | + | 44 | + |
38 | + clocks: | 45 | + clocks: |
39 | + maxItems: 4 | 46 | + maxItems: 4 |
40 | + | 47 | + |
41 | + clock-names: | 48 | + clock-names: |
42 | + items: | 49 | + items: |
43 | + - const: osc | 50 | + - const: osc |
44 | + - const: vctcxo_1m | 51 | + - const: vctcxo_1m |
45 | + - const: vctcxo_3m | 52 | + - const: vctcxo_3m |
46 | + - const: vctcxo_24m | 53 | + - const: vctcxo_24m |
47 | + | 54 | + |
48 | + spacemit,mpmu: | ||
49 | + $ref: /schemas/types.yaml#/definitions/phandle | ||
50 | + description: | ||
51 | + Phandle to the syscon managing "Main PMU (MPMU)" registers. It is used to | ||
52 | + check PLL lock status. | ||
53 | + | ||
54 | + "#clock-cells": | 55 | + "#clock-cells": |
55 | + const: 1 | 56 | + const: 1 |
56 | + description: | 57 | + description: |
57 | + See <dt-bindings/clock/spacemit,k1-ccu.h> for valid indices. | 58 | + See <dt-bindings/clock/spacemit,k1-syscon.h> for valid indices. |
59 | + | ||
60 | + "#power-domain-cells": | ||
61 | + const: 1 | ||
62 | + | ||
63 | + "#reset-cells": | ||
64 | + const: 1 | ||
58 | + | 65 | + |
59 | +required: | 66 | +required: |
60 | + - compatible | 67 | + - compatible |
68 | + - reg | ||
61 | + - clocks | 69 | + - clocks |
62 | + - clock-names | 70 | + - clock-names |
63 | + - "#clock-cells" | 71 | + - "#clock-cells" |
72 | + - "#reset-cells" | ||
64 | + | 73 | + |
65 | +allOf: | 74 | +allOf: |
66 | + - if: | 75 | + - if: |
67 | + properties: | 76 | + properties: |
68 | + compatible: | 77 | + compatible: |
69 | + contains: | 78 | + contains: |
70 | + const: spacemit,k1-ccu-apbs | 79 | + const: spacemit,k1-syscon-apbc |
71 | + then: | 80 | + then: |
81 | + properties: | ||
82 | + "#power-domain-cells": false | ||
83 | + else: | ||
72 | + required: | 84 | + required: |
73 | + - spacemit,mpmu | 85 | + - "#power-domain-cells" |
74 | + else: | ||
75 | + properties: | ||
76 | + spacemit,mpmu: false | ||
77 | + | 86 | + |
78 | +additionalProperties: false | 87 | +additionalProperties: false |
79 | diff --git a/include/dt-bindings/clock/spacemit,k1-ccu.h b/include/dt-bindings/clock/spacemit,k1-ccu.h | 88 | + |
89 | +examples: | ||
90 | + - | | ||
91 | + system-controller@d4050000 { | ||
92 | + compatible = "spacemit,k1-syscon-mpmu"; | ||
93 | + reg = <0xd4050000 0x209c>; | ||
94 | + clocks = <&osc>, <&vctcxo_1m>, <&vctcxo_3m>, <&vctcxo_24m>; | ||
95 | + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", "vctcxo_24m"; | ||
96 | + #clock-cells = <1>; | ||
97 | + #power-domain-cells = <1>; | ||
98 | + #reset-cells = <1>; | ||
99 | + }; | ||
100 | diff --git a/include/dt-bindings/clock/spacemit,k1-syscon.h b/include/dt-bindings/clock/spacemit,k1-syscon.h | ||
80 | new file mode 100644 | 101 | new file mode 100644 |
81 | index XXXXXXX..XXXXXXX | 102 | index XXXXXXX..XXXXXXX |
82 | --- /dev/null | 103 | --- /dev/null |
83 | +++ b/include/dt-bindings/clock/spacemit,k1-ccu.h | 104 | +++ b/include/dt-bindings/clock/spacemit,k1-syscon.h |
84 | @@ -XXX,XX +XXX,XX @@ | 105 | @@ -XXX,XX +XXX,XX @@ |
85 | +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ | 106 | +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ |
86 | +/* | 107 | +/* |
87 | + * Copyright (C) 2024 Haylen Chu <heylenay@outlook.com> | 108 | + * Copyright (C) 2024 Haylen Chu <heylenay@outlook.com> |
88 | + */ | 109 | + */ |
89 | + | 110 | + |
90 | +#ifndef _DT_BINDINGS_SPACEMIT_CCU_H_ | 111 | +#ifndef _DT_BINDINGS_SPACEMIT_CCU_H_ |
91 | +#define _DT_BINDINGS_SPACEMIT_CCU_H_ | 112 | +#define _DT_BINDINGS_SPACEMIT_CCU_H_ |
92 | + | 113 | + |
93 | +/* APBS clocks */ | 114 | +/* MPMU clocks */ |
94 | +#define CLK_PLL1 0 | ||
95 | +#define CLK_PLL2 1 | ||
96 | +#define CLK_PLL3 2 | ||
97 | +#define CLK_PLL1_D2 3 | ||
98 | +#define CLK_PLL1_D3 4 | ||
99 | +#define CLK_PLL1_D4 5 | ||
100 | +#define CLK_PLL1_D5 6 | ||
101 | +#define CLK_PLL1_D6 7 | ||
102 | +#define CLK_PLL1_D7 8 | ||
103 | +#define CLK_PLL1_D8 9 | ||
104 | +#define CLK_PLL1_D11 10 | ||
105 | +#define CLK_PLL1_D13 11 | ||
106 | +#define CLK_PLL1_D23 12 | ||
107 | +#define CLK_PLL1_D64 13 | ||
108 | +#define CLK_PLL1_D10_AUD 14 | ||
109 | +#define CLK_PLL1_D100_AUD 15 | ||
110 | +#define CLK_PLL2_D1 16 | ||
111 | +#define CLK_PLL2_D2 17 | ||
112 | +#define CLK_PLL2_D3 18 | ||
113 | +#define CLK_PLL2_D4 19 | ||
114 | +#define CLK_PLL2_D5 20 | ||
115 | +#define CLK_PLL2_D6 21 | ||
116 | +#define CLK_PLL2_D7 22 | ||
117 | +#define CLK_PLL2_D8 23 | ||
118 | +#define CLK_PLL3_D1 24 | ||
119 | +#define CLK_PLL3_D2 25 | ||
120 | +#define CLK_PLL3_D3 26 | ||
121 | +#define CLK_PLL3_D4 27 | ||
122 | +#define CLK_PLL3_D5 28 | ||
123 | +#define CLK_PLL3_D6 29 | ||
124 | +#define CLK_PLL3_D7 30 | ||
125 | +#define CLK_PLL3_D8 31 | ||
126 | +#define CLK_PLL3_80 32 | ||
127 | +#define CLK_PLL3_40 33 | ||
128 | +#define CLK_PLL3_20 34 | ||
129 | +#define CLK_APBS_NUM 35 | ||
130 | + | ||
131 | +/* MPMU clocks */ | ||
132 | +#define CLK_PLL1_307P2 0 | 115 | +#define CLK_PLL1_307P2 0 |
133 | +#define CLK_PLL1_76P8 1 | 116 | +#define CLK_PLL1_76P8 1 |
134 | +#define CLK_PLL1_61P44 2 | 117 | +#define CLK_PLL1_61P44 2 |
135 | +#define CLK_PLL1_153P6 3 | 118 | +#define CLK_PLL1_153P6 3 |
136 | +#define CLK_PLL1_102P4 4 | 119 | +#define CLK_PLL1_102P4 4 |
... | ... | ||
142 | +#define CLK_PLL1_12P8_WDT 10 | 125 | +#define CLK_PLL1_12P8_WDT 10 |
143 | +#define CLK_PLL1_6P4 11 | 126 | +#define CLK_PLL1_6P4 11 |
144 | +#define CLK_PLL1_3P2 12 | 127 | +#define CLK_PLL1_3P2 12 |
145 | +#define CLK_PLL1_1P6 13 | 128 | +#define CLK_PLL1_1P6 13 |
146 | +#define CLK_PLL1_0P8 14 | 129 | +#define CLK_PLL1_0P8 14 |
147 | +#define CLK_PLL1_351 15 | 130 | +#define CLK_PLL1_409P6 15 |
148 | +#define CLK_PLL1_409P6 16 | 131 | +#define CLK_PLL1_204P8 16 |
149 | +#define CLK_PLL1_204P8 17 | 132 | +#define CLK_PLL1_491 17 |
150 | +#define CLK_PLL1_491 18 | 133 | +#define CLK_PLL1_245P76 18 |
151 | +#define CLK_PLL1_245P76 19 | 134 | +#define CLK_PLL1_614 19 |
152 | +#define CLK_PLL1_614 20 | 135 | +#define CLK_PLL1_47P26 20 |
153 | +#define CLK_PLL1_47P26 21 | 136 | +#define CLK_PLL1_31P5 21 |
154 | +#define CLK_PLL1_31P5 22 | 137 | +#define CLK_PLL1_819 22 |
155 | +#define CLK_PLL1_819 23 | 138 | +#define CLK_PLL1_1228 23 |
156 | +#define CLK_PLL1_1228 24 | 139 | +#define CLK_SLOW_UART 24 |
157 | +#define CLK_SLOW_UART 25 | 140 | +#define CLK_SLOW_UART1 25 |
158 | +#define CLK_SLOW_UART1 26 | 141 | +#define CLK_SLOW_UART2 26 |
159 | +#define CLK_SLOW_UART2 27 | 142 | +#define CLK_WDT 27 |
160 | +#define CLK_WDT 28 | 143 | +#define CLK_RIPC 28 |
161 | +#define CLK_RIPC 29 | 144 | +#define CLK_I2S_SYSCLK 29 |
162 | +#define CLK_I2S_SYSCLK 30 | 145 | +#define CLK_I2S_BCLK 30 |
163 | +#define CLK_I2S_BCLK 31 | 146 | +#define CLK_APB 31 |
164 | +#define CLK_APB 32 | 147 | +#define CLK_WDT_BUS 32 |
165 | +#define CLK_WDT_BUS 33 | 148 | + |
166 | +#define CLK_MPMU_NUM 34 | 149 | +/* APBC clocks */ |
167 | + | ||
168 | +/* APBC clocks */ | ||
169 | +#define CLK_UART0 0 | 150 | +#define CLK_UART0 0 |
170 | +#define CLK_UART2 1 | 151 | +#define CLK_UART2 1 |
171 | +#define CLK_UART3 2 | 152 | +#define CLK_UART3 2 |
172 | +#define CLK_UART4 3 | 153 | +#define CLK_UART4 3 |
173 | +#define CLK_UART5 4 | 154 | +#define CLK_UART5 4 |
... | ... | ||
264 | +#define CLK_ONEWIRE_BUS 95 | 245 | +#define CLK_ONEWIRE_BUS 95 |
265 | +#define CLK_SSPA0_BUS 96 | 246 | +#define CLK_SSPA0_BUS 96 |
266 | +#define CLK_SSPA1_BUS 97 | 247 | +#define CLK_SSPA1_BUS 97 |
267 | +#define CLK_TSEN_BUS 98 | 248 | +#define CLK_TSEN_BUS 98 |
268 | +#define CLK_IPC_AP2AUD_BUS 99 | 249 | +#define CLK_IPC_AP2AUD_BUS 99 |
269 | +#define CLK_APBC_NUM 100 | 250 | + |
270 | + | 251 | +/* APMU clocks */ |
271 | +/* APMU clocks */ | ||
272 | +#define CLK_CCI550 0 | 252 | +#define CLK_CCI550 0 |
273 | +#define CLK_CPU_C0_HI 1 | 253 | +#define CLK_CPU_C0_HI 1 |
274 | +#define CLK_CPU_C0_CORE 2 | 254 | +#define CLK_CPU_C0_CORE 2 |
275 | +#define CLK_CPU_C0_ACE 3 | 255 | +#define CLK_CPU_C0_ACE 3 |
276 | +#define CLK_CPU_C0_TCM 4 | 256 | +#define CLK_CPU_C0_TCM 4 |
... | ... | ||
295 | +#define CLK_EMMC 23 | 275 | +#define CLK_EMMC 23 |
296 | +#define CLK_EMMC_X 24 | 276 | +#define CLK_EMMC_X 24 |
297 | +#define CLK_AUDIO 25 | 277 | +#define CLK_AUDIO 25 |
298 | +#define CLK_HDMI 26 | 278 | +#define CLK_HDMI 26 |
299 | +#define CLK_PMUA_ACLK 27 | 279 | +#define CLK_PMUA_ACLK 27 |
300 | +#define CLK_PCIE0 28 | 280 | +#define CLK_PCIE0_MASTER 28 |
301 | +#define CLK_PCIE1 29 | 281 | +#define CLK_PCIE0_SLAVE 29 |
302 | +#define CLK_PCIE2 30 | 282 | +#define CLK_PCIE0_DBI 30 |
303 | +#define CLK_EMAC0_BUS 31 | 283 | +#define CLK_PCIE1_MASTER 31 |
304 | +#define CLK_EMAC0_PTP 32 | 284 | +#define CLK_PCIE1_SLAVE 32 |
305 | +#define CLK_EMAC1_BUS 33 | 285 | +#define CLK_PCIE1_DBI 33 |
306 | +#define CLK_EMAC1_PTP 34 | 286 | +#define CLK_PCIE2_MASTER 34 |
307 | +#define CLK_JPG 35 | 287 | +#define CLK_PCIE2_SLAVE 35 |
308 | +#define CLK_CCIC2PHY 36 | 288 | +#define CLK_PCIE2_DBI 36 |
309 | +#define CLK_CCIC3PHY 37 | 289 | +#define CLK_EMAC0_BUS 37 |
310 | +#define CLK_CSI 38 | 290 | +#define CLK_EMAC0_PTP 38 |
311 | +#define CLK_CAMM0 39 | 291 | +#define CLK_EMAC1_BUS 39 |
312 | +#define CLK_CAMM1 40 | 292 | +#define CLK_EMAC1_PTP 40 |
313 | +#define CLK_CAMM2 41 | 293 | +#define CLK_JPG 41 |
314 | +#define CLK_ISP_CPP 42 | 294 | +#define CLK_CCIC2PHY 42 |
315 | +#define CLK_ISP_BUS 43 | 295 | +#define CLK_CCIC3PHY 43 |
316 | +#define CLK_ISP 44 | 296 | +#define CLK_CSI 44 |
317 | +#define CLK_DPU_MCLK 45 | 297 | +#define CLK_CAMM0 45 |
318 | +#define CLK_DPU_ESC 46 | 298 | +#define CLK_CAMM1 46 |
319 | +#define CLK_DPU_BIT 47 | 299 | +#define CLK_CAMM2 47 |
320 | +#define CLK_DPU_PXCLK 48 | 300 | +#define CLK_ISP_CPP 48 |
321 | +#define CLK_DPU_HCLK 49 | 301 | +#define CLK_ISP_BUS 49 |
322 | +#define CLK_DPU_SPI 50 | 302 | +#define CLK_ISP 50 |
323 | +#define CLK_DPU_SPI_HBUS 51 | 303 | +#define CLK_DPU_MCLK 51 |
324 | +#define CLK_DPU_SPIBUS 52 | 304 | +#define CLK_DPU_ESC 52 |
325 | +#define CLK_DPU_SPI_ACLK 53 | 305 | +#define CLK_DPU_BIT 53 |
326 | +#define CLK_V2D 54 | 306 | +#define CLK_DPU_PXCLK 54 |
327 | +#define CLK_EMMC_BUS 55 | 307 | +#define CLK_DPU_HCLK 55 |
328 | +#define CLK_APMU_NUM 56 | 308 | +#define CLK_DPU_SPI 56 |
309 | +#define CLK_DPU_SPI_HBUS 57 | ||
310 | +#define CLK_DPU_SPIBUS 58 | ||
311 | +#define CLK_DPU_SPI_ACLK 59 | ||
312 | +#define CLK_V2D 60 | ||
313 | +#define CLK_EMMC_BUS 61 | ||
329 | + | 314 | + |
330 | +#endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */ | 315 | +#endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */ |
331 | -- | 316 | -- |
332 | 2.47.1 | 317 | 2.49.0 | diff view generated by jsdifflib |
1 | Add documentation to describe Spacemit K1 system controller registers. | 1 | Add definition for the PLL found on SpacemiT K1 SoC, which takes the |
---|---|---|---|
2 | external 24MHz oscillator as input and generates clocks in various | ||
3 | frequencies for the system. | ||
2 | 4 | ||
3 | Signed-off-by: Haylen Chu <heylenay@4d2.org> | 5 | Signed-off-by: Haylen Chu <heylenay@4d2.org> |
6 | Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | ||
4 | --- | 7 | --- |
5 | .../soc/spacemit/spacemit,k1-syscon.yaml | 52 +++++++++++++++++++ | 8 | .../bindings/clock/spacemit,k1-pll.yaml | 50 +++++++++++++++++++ |
6 | 1 file changed, 52 insertions(+) | 9 | .../dt-bindings/clock/spacemit,k1-syscon.h | 37 ++++++++++++++ |
7 | create mode 100644 Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml | 10 | 2 files changed, 87 insertions(+) |
11 | create mode 100644 Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml | ||
8 | 12 | ||
9 | diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml | 13 | diff --git a/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml |
10 | new file mode 100644 | 14 | new file mode 100644 |
11 | index XXXXXXX..XXXXXXX | 15 | index XXXXXXX..XXXXXXX |
12 | --- /dev/null | 16 | --- /dev/null |
13 | +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml | 17 | +++ b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml |
14 | @@ -XXX,XX +XXX,XX @@ | 18 | @@ -XXX,XX +XXX,XX @@ |
15 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | 19 | +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause |
16 | +%YAML 1.2 | 20 | +%YAML 1.2 |
17 | +--- | 21 | +--- |
18 | +$id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml# | 22 | +$id: http://devicetree.org/schemas/clock/spacemit,k1-pll.yaml# |
19 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | 23 | +$schema: http://devicetree.org/meta-schemas/core.yaml# |
20 | + | 24 | + |
21 | +title: Spacemit K1 SoC System Controller | 25 | +title: SpacemiT K1 PLL |
22 | + | 26 | + |
23 | +maintainers: | 27 | +maintainers: |
24 | + - Haylen Chu <heylenay@4d2.org> | 28 | + - Haylen Chu <heylenay@4d2.org> |
25 | + | 29 | + |
26 | +description: | ||
27 | + The Spacemit K1 SoC system controller provides access to shared register files | ||
28 | + for related SoC modules, such as clock controller and reset controller. | ||
29 | + | ||
30 | +properties: | 30 | +properties: |
31 | + compatible: | 31 | + compatible: |
32 | + items: | 32 | + const: spacemit,k1-pll |
33 | + - enum: | ||
34 | + - spacemit,k1-apbc-syscon | ||
35 | + - spacemit,k1-apbs-syscon | ||
36 | + - spacemit,k1-apmu-syscon | ||
37 | + - spacemit,k1-mpmu-syscon | ||
38 | + - const: syscon | ||
39 | + - const: simple-mfd | ||
40 | + | 33 | + |
41 | + reg: | 34 | + reg: |
42 | + maxItems: 1 | 35 | + maxItems: 1 |
43 | + | 36 | + |
44 | + clock-controller: | 37 | + clocks: |
45 | + $ref: /schemas/clock/spacemit,k1-ccu.yaml# | 38 | + description: External 24MHz oscillator |
46 | + type: object | 39 | + |
40 | + spacemit,mpmu: | ||
41 | + $ref: /schemas/types.yaml#/definitions/phandle | ||
42 | + description: | ||
43 | + Phandle to the "Main PMU (MPMU)" syscon. It is used to check PLL | ||
44 | + lock status. | ||
45 | + | ||
46 | + "#clock-cells": | ||
47 | + const: 1 | ||
48 | + description: | ||
49 | + See <dt-bindings/clock/spacemit,k1-syscon.h> for valid indices. | ||
47 | + | 50 | + |
48 | +required: | 51 | +required: |
49 | + - compatible | 52 | + - compatible |
50 | + - reg | 53 | + - reg |
54 | + - clocks | ||
55 | + - spacemit,mpmu | ||
56 | + - "#clock-cells" | ||
51 | + | 57 | + |
52 | +additionalProperties: false | 58 | +additionalProperties: false |
53 | + | 59 | + |
54 | +examples: | 60 | +examples: |
55 | + - | | 61 | + - | |
56 | + system-controller@d4050000 { | 62 | + clock-controller@d4090000 { |
57 | + compatible = "spacemit,k1-mpmu-syscon", "syscon", "simple-mfd"; | 63 | + compatible = "spacemit,k1-pll"; |
58 | + reg = <0xd4050000 0x209c>; | 64 | + reg = <0xd4090000 0x1000>; |
65 | + clocks = <&vctcxo_24m>; | ||
66 | + spacemit,mpmu = <&sysctl_mpmu>; | ||
67 | + #clock-cells = <1>; | ||
68 | + }; | ||
69 | diff --git a/include/dt-bindings/clock/spacemit,k1-syscon.h b/include/dt-bindings/clock/spacemit,k1-syscon.h | ||
70 | index XXXXXXX..XXXXXXX 100644 | ||
71 | --- a/include/dt-bindings/clock/spacemit,k1-syscon.h | ||
72 | +++ b/include/dt-bindings/clock/spacemit,k1-syscon.h | ||
73 | @@ -XXX,XX +XXX,XX @@ | ||
74 | #ifndef _DT_BINDINGS_SPACEMIT_CCU_H_ | ||
75 | #define _DT_BINDINGS_SPACEMIT_CCU_H_ | ||
76 | |||
77 | +/* APBS (PLL) clocks */ | ||
78 | +#define CLK_PLL1 0 | ||
79 | +#define CLK_PLL2 1 | ||
80 | +#define CLK_PLL3 2 | ||
81 | +#define CLK_PLL1_D2 3 | ||
82 | +#define CLK_PLL1_D3 4 | ||
83 | +#define CLK_PLL1_D4 5 | ||
84 | +#define CLK_PLL1_D5 6 | ||
85 | +#define CLK_PLL1_D6 7 | ||
86 | +#define CLK_PLL1_D7 8 | ||
87 | +#define CLK_PLL1_D8 9 | ||
88 | +#define CLK_PLL1_D11 10 | ||
89 | +#define CLK_PLL1_D13 11 | ||
90 | +#define CLK_PLL1_D23 12 | ||
91 | +#define CLK_PLL1_D64 13 | ||
92 | +#define CLK_PLL1_D10_AUD 14 | ||
93 | +#define CLK_PLL1_D100_AUD 15 | ||
94 | +#define CLK_PLL2_D1 16 | ||
95 | +#define CLK_PLL2_D2 17 | ||
96 | +#define CLK_PLL2_D3 18 | ||
97 | +#define CLK_PLL2_D4 19 | ||
98 | +#define CLK_PLL2_D5 20 | ||
99 | +#define CLK_PLL2_D6 21 | ||
100 | +#define CLK_PLL2_D7 22 | ||
101 | +#define CLK_PLL2_D8 23 | ||
102 | +#define CLK_PLL3_D1 24 | ||
103 | +#define CLK_PLL3_D2 25 | ||
104 | +#define CLK_PLL3_D3 26 | ||
105 | +#define CLK_PLL3_D4 27 | ||
106 | +#define CLK_PLL3_D5 28 | ||
107 | +#define CLK_PLL3_D6 29 | ||
108 | +#define CLK_PLL3_D7 30 | ||
109 | +#define CLK_PLL3_D8 31 | ||
110 | +#define CLK_PLL3_80 32 | ||
111 | +#define CLK_PLL3_40 33 | ||
112 | +#define CLK_PLL3_20 34 | ||
59 | + | 113 | + |
60 | + clock-controller { | 114 | /* MPMU clocks */ |
61 | + compatible = "spacemit,k1-ccu-mpmu"; | 115 | #define CLK_PLL1_307P2 0 |
62 | + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, <&vctcxo_24m>; | 116 | #define CLK_PLL1_76P8 1 |
63 | + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", "vctcxo_24m"; | ||
64 | + #clock-cells = <1>; | ||
65 | + }; | ||
66 | + }; | ||
67 | -- | 117 | -- |
68 | 2.47.1 | 118 | 2.49.0 | diff view generated by jsdifflib |
1 | The clock tree of K1 SoC contains three main types of clock hardware | 1 | The clock tree of K1 SoC contains three main types of clock hardware |
---|---|---|---|
2 | (PLL/DDN/MIX) and is managed by several independent controllers in | 2 | (PLL/DDN/MIX) and has control registers split into several multifunction |
3 | different SoC parts (APBC, APBS and etc.), thus different compatible | 3 | devices: APBS (PLLs), MPMU, APBC and APMU. |
4 | strings are added to distinguish them. | ||
5 | 4 | ||
6 | Some controllers may share IO region with reset controller and other low | 5 | All register operations are done through regmap to ensure atomiciy |
7 | speed peripherals like watchdog, so all register operations are done | 6 | between concurrent operations of clock driver and reset, |
8 | through regmap to avoid competition. | 7 | power-domain driver that will be introduced in the future. |
9 | 8 | ||
10 | Signed-off-by: Haylen Chu <heylenay@4d2.org> | 9 | Signed-off-by: Haylen Chu <heylenay@4d2.org> |
11 | --- | 10 | --- |
12 | drivers/clk/Kconfig | 1 + | 11 | drivers/clk/Kconfig | 1 + |
13 | drivers/clk/Makefile | 1 + | 12 | drivers/clk/Makefile | 1 + |
14 | drivers/clk/spacemit/Kconfig | 20 + | 13 | drivers/clk/spacemit/Kconfig | 18 + |
15 | drivers/clk/spacemit/Makefile | 5 + | 14 | drivers/clk/spacemit/Makefile | 5 + |
16 | drivers/clk/spacemit/ccu-k1.c | 1747 +++++++++++++++++++++++++++++ | 15 | drivers/clk/spacemit/apbc_clks | 100 +++ |
17 | drivers/clk/spacemit/ccu_common.h | 51 + | 16 | drivers/clk/spacemit/ccu-k1.c | 1316 +++++++++++++++++++++++++++++ |
18 | drivers/clk/spacemit/ccu_ddn.c | 140 +++ | 17 | drivers/clk/spacemit/ccu_common.h | 48 ++ |
19 | drivers/clk/spacemit/ccu_ddn.h | 84 ++ | 18 | drivers/clk/spacemit/ccu_ddn.c | 83 ++ |
20 | drivers/clk/spacemit/ccu_mix.c | 304 +++++ | 19 | drivers/clk/spacemit/ccu_ddn.h | 47 ++ |
21 | drivers/clk/spacemit/ccu_mix.h | 309 +++++ | 20 | drivers/clk/spacemit/ccu_mix.c | 268 ++++++ |
22 | drivers/clk/spacemit/ccu_pll.c | 189 ++++ | 21 | drivers/clk/spacemit/ccu_mix.h | 218 +++++ |
23 | drivers/clk/spacemit/ccu_pll.h | 80 ++ | 22 | drivers/clk/spacemit/ccu_pll.c | 157 ++++ |
24 | 12 files changed, 2931 insertions(+) | 23 | drivers/clk/spacemit/ccu_pll.h | 86 ++ |
24 | 13 files changed, 2348 insertions(+) | ||
25 | create mode 100644 drivers/clk/spacemit/Kconfig | 25 | create mode 100644 drivers/clk/spacemit/Kconfig |
26 | create mode 100644 drivers/clk/spacemit/Makefile | 26 | create mode 100644 drivers/clk/spacemit/Makefile |
27 | create mode 100644 drivers/clk/spacemit/apbc_clks | ||
27 | create mode 100644 drivers/clk/spacemit/ccu-k1.c | 28 | create mode 100644 drivers/clk/spacemit/ccu-k1.c |
28 | create mode 100644 drivers/clk/spacemit/ccu_common.h | 29 | create mode 100644 drivers/clk/spacemit/ccu_common.h |
29 | create mode 100644 drivers/clk/spacemit/ccu_ddn.c | 30 | create mode 100644 drivers/clk/spacemit/ccu_ddn.c |
30 | create mode 100644 drivers/clk/spacemit/ccu_ddn.h | 31 | create mode 100644 drivers/clk/spacemit/ccu_ddn.h |
31 | create mode 100644 drivers/clk/spacemit/ccu_mix.c | 32 | create mode 100644 drivers/clk/spacemit/ccu_mix.c |
... | ... | ||
64 | +++ b/drivers/clk/spacemit/Kconfig | 65 | +++ b/drivers/clk/spacemit/Kconfig |
65 | @@ -XXX,XX +XXX,XX @@ | 66 | @@ -XXX,XX +XXX,XX @@ |
66 | +# SPDX-License-Identifier: GPL-2.0-only | 67 | +# SPDX-License-Identifier: GPL-2.0-only |
67 | + | 68 | + |
68 | +config SPACEMIT_CCU | 69 | +config SPACEMIT_CCU |
69 | + tristate "Clock support for Spacemit SoCs" | 70 | + tristate "Clock support for SpacemiT SoCs" |
70 | + default y | ||
71 | + depends on ARCH_SPACEMIT || COMPILE_TEST | 71 | + depends on ARCH_SPACEMIT || COMPILE_TEST |
72 | + select MFD_SYSCON | 72 | + select MFD_SYSCON |
73 | + help | 73 | + help |
74 | + Say Y to enable clock controller unit support for Spacemit SoCs. | 74 | + Say Y to enable clock controller unit support for SpacemiT SoCs. |
75 | + | 75 | + |
76 | +if SPACEMIT_CCU | 76 | +if SPACEMIT_CCU |
77 | + | 77 | + |
78 | +config SPACEMIT_K1_CCU | 78 | +config SPACEMIT_K1_CCU |
79 | + tristate "Support for Spacemit K1 SoC" | 79 | + tristate "Support for SpacemiT K1 SoC" |
80 | + default y | ||
81 | + depends on ARCH_SPACEMIT || COMPILE_TEST | 80 | + depends on ARCH_SPACEMIT || COMPILE_TEST |
82 | + help | 81 | + help |
83 | + Support for clock controller unit in Spacemit K1 SoC. | 82 | + Support for clock controller unit in SpacemiT K1 SoC. |
84 | + | 83 | + |
85 | +endif | 84 | +endif |
86 | diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile | 85 | diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile |
87 | new file mode 100644 | 86 | new file mode 100644 |
88 | index XXXXXXX..XXXXXXX | 87 | index XXXXXXX..XXXXXXX |
... | ... | ||
92 | +# SPDX-License-Identifier: GPL-2.0 | 91 | +# SPDX-License-Identifier: GPL-2.0 |
93 | + | 92 | + |
94 | +obj-$(CONFIG_SPACEMIT_K1_CCU) = spacemit-ccu-k1.o | 93 | +obj-$(CONFIG_SPACEMIT_K1_CCU) = spacemit-ccu-k1.o |
95 | +spacemit-ccu-k1-y = ccu_pll.o ccu_mix.o ccu_ddn.o | 94 | +spacemit-ccu-k1-y = ccu_pll.o ccu_mix.o ccu_ddn.o |
96 | +spacemit-ccu-k1-y += ccu-k1.o | 95 | +spacemit-ccu-k1-y += ccu-k1.o |
97 | diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c | 96 | diff --git a/drivers/clk/spacemit/apbc_clks b/drivers/clk/spacemit/apbc_clks |
98 | new file mode 100644 | 97 | new file mode 100644 |
99 | index XXXXXXX..XXXXXXX | 98 | index XXXXXXX..XXXXXXX |
100 | --- /dev/null | 99 | --- /dev/null |
101 | +++ b/drivers/clk/spacemit/ccu-k1.c | 100 | +++ b/drivers/clk/spacemit/apbc_clks |
102 | @@ -XXX,XX +XXX,XX @@ | 101 | @@ -XXX,XX +XXX,XX @@ |
103 | +// SPDX-License-Identifier: GPL-2.0-only | ||
104 | +/* | ||
105 | + * Copyright (c) 2024 SpacemiT Technology Co. Ltd | ||
106 | + * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org> | ||
107 | + */ | ||
108 | + | ||
109 | +#include <linux/clk-provider.h> | ||
110 | +#include <linux/delay.h> | ||
111 | +#include <linux/mfd/syscon.h> | ||
112 | +#include <linux/module.h> | ||
113 | +#include <linux/platform_device.h> | ||
114 | + | ||
115 | +#include "ccu_common.h" | ||
116 | +#include "ccu_pll.h" | ||
117 | +#include "ccu_mix.h" | ||
118 | +#include "ccu_ddn.h" | ||
119 | + | ||
120 | +#include <dt-bindings/clock/spacemit,k1-ccu.h> | ||
121 | + | ||
122 | +/* APBS register offset */ | ||
123 | +/* pll1 */ | ||
124 | +#define APB_SPARE1_REG 0x100 | ||
125 | +#define APB_SPARE2_REG 0x104 | ||
126 | +#define APB_SPARE3_REG 0x108 | ||
127 | +/* pll2 */ | ||
128 | +#define APB_SPARE7_REG 0x118 | ||
129 | +#define APB_SPARE8_REG 0x11c | ||
130 | +#define APB_SPARE9_REG 0x120 | ||
131 | +/* pll3 */ | ||
132 | +#define APB_SPARE10_REG 0x124 | ||
133 | +#define APB_SPARE11_REG 0x128 | ||
134 | +#define APB_SPARE12_REG 0x12c | ||
135 | + | ||
136 | +/* MPMU register offset */ | ||
137 | +#define MPMU_POSR 0x10 | ||
138 | +#define POSR_PLL1_LOCK BIT(27) | ||
139 | +#define POSR_PLL2_LOCK BIT(28) | ||
140 | +#define POSR_PLL3_LOCK BIT(29) | ||
141 | + | ||
142 | +#define MPMU_WDTPCR 0x200 | ||
143 | +#define MPMU_RIPCCR 0x210 | ||
144 | +#define MPMU_ACGR 0x1024 | ||
145 | +#define MPMU_SUCCR 0x14 | ||
146 | +#define MPMU_ISCCR 0x44 | ||
147 | +#define MPMU_SUCCR_1 0x10b0 | ||
148 | +#define MPMU_APBCSCR 0x1050 | ||
149 | + | ||
150 | +/* APBC register offset */ | ||
151 | +#define APBC_UART1_CLK_RST 0x0 | ||
152 | +#define APBC_UART2_CLK_RST 0x4 | ||
153 | +#define APBC_GPIO_CLK_RST 0x8 | ||
154 | +#define APBC_PWM0_CLK_RST 0xc | ||
155 | +#define APBC_PWM1_CLK_RST 0x10 | ||
156 | +#define APBC_PWM2_CLK_RST 0x14 | ||
157 | +#define APBC_PWM3_CLK_RST 0x18 | ||
158 | +#define APBC_TWSI8_CLK_RST 0x20 | ||
159 | +#define APBC_UART3_CLK_RST 0x24 | ||
160 | +#define APBC_RTC_CLK_RST 0x28 | ||
161 | +#define APBC_TWSI0_CLK_RST 0x2c | ||
162 | +#define APBC_TWSI1_CLK_RST 0x30 | ||
163 | +#define APBC_TIMERS1_CLK_RST 0x34 | ||
164 | +#define APBC_TWSI2_CLK_RST 0x38 | ||
165 | +#define APBC_AIB_CLK_RST 0x3c | ||
166 | +#define APBC_TWSI4_CLK_RST 0x40 | ||
167 | +#define APBC_TIMERS2_CLK_RST 0x44 | ||
168 | +#define APBC_ONEWIRE_CLK_RST 0x48 | ||
169 | +#define APBC_TWSI5_CLK_RST 0x4c | ||
170 | +#define APBC_DRO_CLK_RST 0x58 | ||
171 | +#define APBC_IR_CLK_RST 0x5c | ||
172 | +#define APBC_TWSI6_CLK_RST 0x60 | ||
173 | +#define APBC_COUNTER_CLK_SEL 0x64 | ||
174 | +#define APBC_TWSI7_CLK_RST 0x68 | ||
175 | +#define APBC_TSEN_CLK_RST 0x6c | ||
176 | +#define APBC_UART4_CLK_RST 0x70 | ||
177 | +#define APBC_UART5_CLK_RST 0x74 | ||
178 | +#define APBC_UART6_CLK_RST 0x78 | ||
179 | +#define APBC_SSP3_CLK_RST 0x7c | ||
180 | +#define APBC_SSPA0_CLK_RST 0x80 | ||
181 | +#define APBC_SSPA1_CLK_RST 0x84 | ||
182 | +#define APBC_IPC_AP2AUD_CLK_RST 0x90 | ||
183 | +#define APBC_UART7_CLK_RST 0x94 | ||
184 | +#define APBC_UART8_CLK_RST 0x98 | ||
185 | +#define APBC_UART9_CLK_RST 0x9c | ||
186 | +#define APBC_CAN0_CLK_RST 0xa0 | ||
187 | +#define APBC_PWM4_CLK_RST 0xa8 | ||
188 | +#define APBC_PWM5_CLK_RST 0xac | ||
189 | +#define APBC_PWM6_CLK_RST 0xb0 | ||
190 | +#define APBC_PWM7_CLK_RST 0xb4 | ||
191 | +#define APBC_PWM8_CLK_RST 0xb8 | ||
192 | +#define APBC_PWM9_CLK_RST 0xbc | ||
193 | +#define APBC_PWM10_CLK_RST 0xc0 | ||
194 | +#define APBC_PWM11_CLK_RST 0xc4 | ||
195 | +#define APBC_PWM12_CLK_RST 0xc8 | ||
196 | +#define APBC_PWM13_CLK_RST 0xcc | ||
197 | +#define APBC_PWM14_CLK_RST 0xd0 | ||
198 | +#define APBC_PWM15_CLK_RST 0xd4 | ||
199 | +#define APBC_PWM16_CLK_RST 0xd8 | ||
200 | +#define APBC_PWM17_CLK_RST 0xdc | ||
201 | +#define APBC_PWM18_CLK_RST 0xe0 | ||
202 | +#define APBC_PWM19_CLK_RST 0xe4 | ||
203 | + | ||
204 | +/* APMU register offset */ | ||
205 | +#define APMU_CCI550_CLK_CTRL 0x300 | ||
206 | +#define APMU_CPU_C0_CLK_CTRL 0x38C | ||
207 | +#define APMU_CPU_C1_CLK_CTRL 0x390 | ||
208 | +#define APMU_JPG_CLK_RES_CTRL 0x20 | ||
209 | +#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x24 | ||
210 | +#define APMU_ISP_CLK_RES_CTRL 0x38 | ||
211 | +#define APMU_LCD_CLK_RES_CTRL1 0x44 | ||
212 | +#define APMU_LCD_SPI_CLK_RES_CTRL 0x48 | ||
213 | +#define APMU_LCD_CLK_RES_CTRL2 0x4c | ||
214 | +#define APMU_CCIC_CLK_RES_CTRL 0x50 | ||
215 | +#define APMU_SDH0_CLK_RES_CTRL 0x54 | ||
216 | +#define APMU_SDH1_CLK_RES_CTRL 0x58 | ||
217 | +#define APMU_USB_CLK_RES_CTRL 0x5c | ||
218 | +#define APMU_QSPI_CLK_RES_CTRL 0x60 | ||
219 | +#define APMU_USB_CLK_RES_CTRL 0x5c | ||
220 | +#define APMU_DMA_CLK_RES_CTRL 0x64 | ||
221 | +#define APMU_AES_CLK_RES_CTRL 0x68 | ||
222 | +#define APMU_VPU_CLK_RES_CTRL 0xa4 | ||
223 | +#define APMU_GPU_CLK_RES_CTRL 0xcc | ||
224 | +#define APMU_SDH2_CLK_RES_CTRL 0xe0 | ||
225 | +#define APMU_PMUA_MC_CTRL 0xe8 | ||
226 | +#define APMU_PMU_CC2_AP 0x100 | ||
227 | +#define APMU_PMUA_EM_CLK_RES_CTRL 0x104 | ||
228 | +#define APMU_AUDIO_CLK_RES_CTRL 0x14c | ||
229 | +#define APMU_HDMI_CLK_RES_CTRL 0x1B8 | ||
230 | +#define APMU_CCI550_CLK_CTRL 0x300 | ||
231 | +#define APMU_ACLK_CLK_CTRL 0x388 | ||
232 | +#define APMU_CPU_C0_CLK_CTRL 0x38C | ||
233 | +#define APMU_CPU_C1_CLK_CTRL 0x390 | ||
234 | +#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc | ||
235 | +#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4 | ||
236 | +#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc | ||
237 | +#define APMU_EMAC0_CLK_RES_CTRL 0x3e4 | ||
238 | +#define APMU_EMAC1_CLK_RES_CTRL 0x3ec | ||
239 | + | ||
240 | +/* APBS clocks start */ | ||
241 | + | ||
242 | +/* Frequency of pll{1,2} should not be updated at runtime */ | ||
243 | +static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = { | ||
244 | + CCU_PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd), | ||
245 | +}; | ||
246 | + | ||
247 | +static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = { | ||
248 | + CCU_PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000), | ||
249 | +}; | ||
250 | + | ||
251 | +static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = { | ||
252 | + CCU_PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000), | ||
253 | + CCU_PLL_RATE(3200000000UL, 0x67, 0xdd, 0x50, 0x00, 0x43, 0xeaaaab), | ||
254 | + CCU_PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd), | ||
255 | +}; | ||
256 | + | ||
257 | +static CCU_PLL_DEFINE(pll1, "pll1", pll1_rate_tbl, | ||
258 | + APB_SPARE1_REG, APB_SPARE2_REG, APB_SPARE3_REG, | ||
259 | + MPMU_POSR, POSR_PLL1_LOCK, CLK_SET_RATE_GATE); | ||
260 | +static CCU_PLL_DEFINE(pll2, "pll2", pll2_rate_tbl, | ||
261 | + APB_SPARE7_REG, APB_SPARE8_REG, APB_SPARE9_REG, | ||
262 | + MPMU_POSR, POSR_PLL2_LOCK, CLK_SET_RATE_GATE); | ||
263 | +static CCU_PLL_DEFINE(pll3, "pll3", pll3_rate_tbl, | ||
264 | + APB_SPARE10_REG, APB_SPARE11_REG, APB_SPARE12_REG, | ||
265 | + MPMU_POSR, POSR_PLL3_LOCK, 0); | ||
266 | + | ||
267 | +static CCU_GATE_FACTOR_DEFINE(pll1_d2, "pll1_d2", CCU_PARENT_HW(pll1), | ||
268 | + APB_SPARE2_REG, | ||
269 | + BIT(1), BIT(1), 0, 2, 1, 0); | ||
270 | +static CCU_GATE_FACTOR_DEFINE(pll1_d3, "pll1_d3", CCU_PARENT_HW(pll1), | ||
271 | + APB_SPARE2_REG, | ||
272 | + BIT(2), BIT(2), 0, 3, 1, 0); | ||
273 | +static CCU_GATE_FACTOR_DEFINE(pll1_d4, "pll1_d4", CCU_PARENT_HW(pll1), | ||
274 | + APB_SPARE2_REG, | ||
275 | + BIT(3), BIT(3), 0, 4, 1, 0); | ||
276 | +static CCU_GATE_FACTOR_DEFINE(pll1_d5, "pll1_d5", CCU_PARENT_HW(pll1), | ||
277 | + APB_SPARE2_REG, | ||
278 | + BIT(4), BIT(4), 0, 5, 1, 0); | ||
279 | +static CCU_GATE_FACTOR_DEFINE(pll1_d6, "pll1_d6", CCU_PARENT_HW(pll1), | ||
280 | + APB_SPARE2_REG, | ||
281 | + BIT(5), BIT(5), 0, 6, 1, 0); | ||
282 | +static CCU_GATE_FACTOR_DEFINE(pll1_d7, "pll1_d7", CCU_PARENT_HW(pll1), | ||
283 | + APB_SPARE2_REG, | ||
284 | + BIT(6), BIT(6), 0, 7, 1, 0); | ||
285 | +static CCU_GATE_FACTOR_DEFINE(pll1_d8, "pll1_d8", CCU_PARENT_HW(pll1), | ||
286 | + APB_SPARE2_REG, | ||
287 | + BIT(7), BIT(7), 0, 8, 1, 0); | ||
288 | +static CCU_GATE_FACTOR_DEFINE(pll1_d11_223p4, "pll1_d11_223p4", CCU_PARENT_HW(pll1), | ||
289 | + APB_SPARE2_REG, | ||
290 | + BIT(15), BIT(15), 0, 11, 1, 0); | ||
291 | +static CCU_GATE_FACTOR_DEFINE(pll1_d13_189, "pll1_d13_189", CCU_PARENT_HW(pll1), | ||
292 | + APB_SPARE2_REG, | ||
293 | + BIT(16), BIT(16), 0, 13, 1, 0); | ||
294 | +static CCU_GATE_FACTOR_DEFINE(pll1_d23_106p8, "pll1_d23_106p8", CCU_PARENT_HW(pll1), | ||
295 | + APB_SPARE2_REG, | ||
296 | + BIT(20), BIT(20), 0, 23, 1, 0); | ||
297 | +static CCU_GATE_FACTOR_DEFINE(pll1_d64_38p4, "pll1_d64_38p4", CCU_PARENT_HW(pll1), | ||
298 | + APB_SPARE2_REG, | ||
299 | + BIT(0), BIT(0), 0, 64, 1, 0); | ||
300 | +static CCU_GATE_FACTOR_DEFINE(pll1_aud_245p7, "pll1_aud_245p7", CCU_PARENT_HW(pll1), | ||
301 | + APB_SPARE2_REG, | ||
302 | + BIT(10), BIT(10), 0, 10, 1, 0); | ||
303 | +static CCU_GATE_FACTOR_DEFINE(pll1_aud_24p5, "pll1_aud_24p5", CCU_PARENT_HW(pll1), | ||
304 | + APB_SPARE2_REG, | ||
305 | + BIT(11), BIT(11), 0, 100, 1, 0); | ||
306 | + | ||
307 | +static CCU_GATE_FACTOR_DEFINE(pll2_d1, "pll2_d1", CCU_PARENT_HW(pll2), | ||
308 | + APB_SPARE8_REG, | ||
309 | + BIT(0), BIT(0), 0, 1, 1, 0); | ||
310 | +static CCU_GATE_FACTOR_DEFINE(pll2_d2, "pll2_d2", CCU_PARENT_HW(pll2), | ||
311 | + APB_SPARE8_REG, | ||
312 | + BIT(1), BIT(1), 0, 2, 1, 0); | ||
313 | +static CCU_GATE_FACTOR_DEFINE(pll2_d3, "pll2_d3", CCU_PARENT_HW(pll2), | ||
314 | + APB_SPARE8_REG, | ||
315 | + BIT(2), BIT(2), 0, 3, 1, 0); | ||
316 | +static CCU_GATE_FACTOR_DEFINE(pll2_d4, "pll2_d4", CCU_PARENT_HW(pll2), | ||
317 | + APB_SPARE8_REG, | ||
318 | + BIT(3), BIT(3), 0, 4, 1, 0); | ||
319 | +static CCU_GATE_FACTOR_DEFINE(pll2_d5, "pll2_d5", CCU_PARENT_HW(pll2), | ||
320 | + APB_SPARE8_REG, | ||
321 | + BIT(4), BIT(4), 0, 5, 1, 0); | ||
322 | +static CCU_GATE_FACTOR_DEFINE(pll2_d6, "pll2_d6", CCU_PARENT_HW(pll2), | ||
323 | + APB_SPARE8_REG, | ||
324 | + BIT(5), BIT(5), 0, 6, 1, 0); | ||
325 | +static CCU_GATE_FACTOR_DEFINE(pll2_d7, "pll2_d7", CCU_PARENT_HW(pll2), | ||
326 | + APB_SPARE8_REG, | ||
327 | + BIT(6), BIT(6), 0, 7, 1, 0); | ||
328 | +static CCU_GATE_FACTOR_DEFINE(pll2_d8, "pll2_d8", CCU_PARENT_HW(pll2), | ||
329 | + APB_SPARE8_REG, | ||
330 | + BIT(7), BIT(7), 0, 8, 1, 0); | ||
331 | + | ||
332 | +static CCU_GATE_FACTOR_DEFINE(pll3_d1, "pll3_d1", CCU_PARENT_HW(pll3), | ||
333 | + APB_SPARE11_REG, | ||
334 | + BIT(0), BIT(0), 0, 1, 1, 0); | ||
335 | +static CCU_GATE_FACTOR_DEFINE(pll3_d2, "pll3_d2", CCU_PARENT_HW(pll3), | ||
336 | + APB_SPARE11_REG, | ||
337 | + BIT(1), BIT(1), 0, 2, 1, 0); | ||
338 | +static CCU_GATE_FACTOR_DEFINE(pll3_d3, "pll3_d3", CCU_PARENT_HW(pll3), | ||
339 | + APB_SPARE11_REG, | ||
340 | + BIT(2), BIT(2), 0, 3, 1, 0); | ||
341 | +static CCU_GATE_FACTOR_DEFINE(pll3_d4, "pll3_d4", CCU_PARENT_HW(pll3), | ||
342 | + APB_SPARE11_REG, | ||
343 | + BIT(3), BIT(3), 0, 4, 1, 0); | ||
344 | +static CCU_GATE_FACTOR_DEFINE(pll3_d5, "pll3_d5", CCU_PARENT_HW(pll3), | ||
345 | + APB_SPARE11_REG, | ||
346 | + BIT(4), BIT(4), 0, 5, 1, 0); | ||
347 | +static CCU_GATE_FACTOR_DEFINE(pll3_d6, "pll3_d6", CCU_PARENT_HW(pll3), | ||
348 | + APB_SPARE11_REG, | ||
349 | + BIT(5), BIT(5), 0, 6, 1, 0); | ||
350 | +static CCU_GATE_FACTOR_DEFINE(pll3_d7, "pll3_d7", CCU_PARENT_HW(pll3), | ||
351 | + APB_SPARE11_REG, | ||
352 | + BIT(6), BIT(6), 0, 7, 1, 0); | ||
353 | +static CCU_GATE_FACTOR_DEFINE(pll3_d8, "pll3_d8", CCU_PARENT_HW(pll3), | ||
354 | + APB_SPARE11_REG, | ||
355 | + BIT(7), BIT(7), 0, 8, 1, 0); | ||
356 | + | ||
357 | +static CCU_FACTOR_DEFINE(pll3_20, "pll3_20", CCU_PARENT_HW(pll3_d8), 20, 1); | ||
358 | +static CCU_FACTOR_DEFINE(pll3_40, "pll3_40", CCU_PARENT_HW(pll3_d8), 10, 1); | ||
359 | +static CCU_FACTOR_DEFINE(pll3_80, "pll3_80", CCU_PARENT_HW(pll3_d8), 5, 1); | ||
360 | + | ||
361 | +/* APBS clocks end */ | ||
362 | + | ||
363 | +/* MPMU clocks start */ | ||
364 | +static CCU_GATE_DEFINE(pll1_d8_307p2, "pll1_d8_307p2", CCU_PARENT_HW(pll1_d8), | ||
365 | + MPMU_ACGR, | ||
366 | + BIT(13), BIT(13), 0, 0); | ||
367 | +static CCU_FACTOR_DEFINE(pll1_d32_76p8, "pll1_d32_76p8", CCU_PARENT_HW(pll1_d8_307p2), | ||
368 | + 4, 1); | ||
369 | +static CCU_FACTOR_DEFINE(pll1_d40_61p44, "pll1_d40_61p44", CCU_PARENT_HW(pll1_d8_307p2), | ||
370 | + 5, 1); | ||
371 | +static CCU_FACTOR_DEFINE(pll1_d16_153p6, "pll1_d16_153p6", CCU_PARENT_HW(pll1_d8), | ||
372 | + 2, 1); | ||
373 | +static CCU_GATE_FACTOR_DEFINE(pll1_d24_102p4, "pll1_d24_102p4", CCU_PARENT_HW(pll1_d8), | ||
374 | + MPMU_ACGR, | ||
375 | + BIT(12), BIT(12), 0, 3, 1, 0); | ||
376 | +static CCU_GATE_FACTOR_DEFINE(pll1_d48_51p2, "pll1_d48_51p2", CCU_PARENT_HW(pll1_d8), | ||
377 | + MPMU_ACGR, | ||
378 | + BIT(7), BIT(7), 0, 6, 1, 0); | ||
379 | +static CCU_GATE_FACTOR_DEFINE(pll1_d48_51p2_ap, "pll1_d48_51p2_ap", CCU_PARENT_HW(pll1_d8), | ||
380 | + MPMU_ACGR, | ||
381 | + BIT(11), BIT(11), 0, 6, 1, 0); | ||
382 | +static CCU_GATE_FACTOR_DEFINE(pll1_m3d128_57p6, "pll1_m3d128_57p6", CCU_PARENT_HW(pll1_d8), | ||
383 | + MPMU_ACGR, | ||
384 | + BIT(8), BIT(8), 0, 16, 3, 0); | ||
385 | +static CCU_GATE_FACTOR_DEFINE(pll1_d96_25p6, "pll1_d96_25p6", CCU_PARENT_HW(pll1_d8), | ||
386 | + MPMU_ACGR, | ||
387 | + BIT(4), BIT(4), 0, 12, 1, 0); | ||
388 | +static CCU_GATE_FACTOR_DEFINE(pll1_d192_12p8, "pll1_d192_12p8", CCU_PARENT_HW(pll1_d8), | ||
389 | + MPMU_ACGR, | ||
390 | + BIT(3), BIT(3), 0, 24, 1, 0); | ||
391 | +static CCU_GATE_FACTOR_DEFINE(pll1_d192_12p8_wdt, "pll1_d192_12p8_wdt", CCU_PARENT_HW(pll1_d8), | ||
392 | + MPMU_ACGR, | ||
393 | + BIT(19), BIT(19), 0x0, 24, 1, 0); | ||
394 | +static CCU_GATE_FACTOR_DEFINE(pll1_d384_6p4, "pll1_d384_6p4", CCU_PARENT_HW(pll1_d8), | ||
395 | + MPMU_ACGR, | ||
396 | + BIT(2), BIT(2), 0, 48, 1, 0); | ||
397 | +static CCU_FACTOR_DEFINE(pll1_d768_3p2, "pll1_d768_3p2", CCU_PARENT_HW(pll1_d384_6p4), | ||
398 | + 2, 1); | ||
399 | +static CCU_FACTOR_DEFINE(pll1_d1536_1p6, "pll1_d1536_1p6", CCU_PARENT_HW(pll1_d384_6p4), | ||
400 | + 4, 1); | ||
401 | +static CCU_FACTOR_DEFINE(pll1_d3072_0p8, "pll1_d3072_0p8", CCU_PARENT_HW(pll1_d384_6p4), | ||
402 | + 8, 1); | ||
403 | + | ||
404 | +static CCU_FACTOR_DEFINE(pll1_d7_351p08, "pll1_d7_351p08", CCU_PARENT_HW(pll1_d7), | ||
405 | + 1, 1); | ||
406 | + | ||
407 | +static CCU_GATE_DEFINE(pll1_d6_409p6, "pll1_d6_409p6", CCU_PARENT_HW(pll1_d6), | ||
408 | + MPMU_ACGR, | ||
409 | + BIT(0), BIT(0), 0, 0); | ||
410 | +static CCU_GATE_FACTOR_DEFINE(pll1_d12_204p8, "pll1_d12_204p8", CCU_PARENT_HW(pll1_d6), | ||
411 | + MPMU_ACGR, | ||
412 | + BIT(5), BIT(5), 0, 2, 1, 0); | ||
413 | + | ||
414 | +static CCU_GATE_DEFINE(pll1_d5_491p52, "pll1_d5_491p52", CCU_PARENT_HW(pll1_d5), | ||
415 | + MPMU_ACGR, | ||
416 | + BIT(21), BIT(21), 0, 0); | ||
417 | +static CCU_GATE_FACTOR_DEFINE(pll1_d10_245p76, "pll1_d10_245p76", CCU_PARENT_HW(pll1_d5), | ||
418 | + MPMU_ACGR, | ||
419 | + BIT(18), BIT(18), 0, 2, 1, 0); | ||
420 | + | ||
421 | +static CCU_GATE_DEFINE(pll1_d4_614p4, "pll1_d4_614p4", CCU_PARENT_HW(pll1_d4), | ||
422 | + MPMU_ACGR, | ||
423 | + BIT(15), BIT(15), 0, 0); | ||
424 | +static CCU_GATE_FACTOR_DEFINE(pll1_d52_47p26, "pll1_d52_47p26", CCU_PARENT_HW(pll1_d4), | ||
425 | + MPMU_ACGR, | ||
426 | + BIT(10), BIT(10), 0, 13, 1, 0); | ||
427 | +static CCU_GATE_FACTOR_DEFINE(pll1_d78_31p5, "pll1_d78_31p5", CCU_PARENT_HW(pll1_d4), | ||
428 | + MPMU_ACGR, | ||
429 | + BIT(6), BIT(6), 0, 39, 2, 0); | ||
430 | + | ||
431 | +static CCU_GATE_DEFINE(pll1_d3_819p2, "pll1_d3_819p2", CCU_PARENT_HW(pll1_d3), | ||
432 | + MPMU_ACGR, | ||
433 | + BIT(14), BIT(14), 0, 0); | ||
434 | + | ||
435 | +static CCU_GATE_DEFINE(pll1_d2_1228p8, "pll1_d2_1228p8", CCU_PARENT_HW(pll1_d2), | ||
436 | + MPMU_ACGR, | ||
437 | + BIT(16), BIT(16), 0, 0); | ||
438 | + | ||
439 | +static struct ccu_ddn_info uart_ddn_mask_info = { | ||
440 | + .factor = 2, | ||
441 | + .num_mask = 0x1fff, | ||
442 | + .den_mask = 0x1fff, | ||
443 | + .num_shift = 16, | ||
444 | + .den_shift = 0, | ||
445 | +}; | ||
446 | +static struct ccu_ddn_tbl slow_uart1_tbl[] = { | ||
447 | + { .num = 125, .den = 24 }, | ||
448 | +}; | ||
449 | +static struct ccu_ddn_tbl slow_uart2_tbl[] = { | ||
450 | + { .num = 6144, .den = 960 }, | ||
451 | +}; | ||
452 | +static CCU_GATE_DEFINE(slow_uart, "slow_uart", CCU_PARENT_NAME(osc), | ||
453 | + MPMU_ACGR, | ||
454 | + BIT(1), BIT(1), 0, CLK_IGNORE_UNUSED); | ||
455 | +static CCU_DDN_DEFINE(slow_uart1_14p74, "slow_uart1_14p74", pll1_d16_153p6, | ||
456 | + &uart_ddn_mask_info, slow_uart1_tbl, | ||
457 | + MPMU_SUCCR, 0); | ||
458 | +static CCU_DDN_DEFINE(slow_uart2_48, "slow_uart2_48", pll1_d4_614p4, | ||
459 | + &uart_ddn_mask_info, slow_uart2_tbl, | ||
460 | + MPMU_SUCCR_1, 0); | ||
461 | + | ||
462 | +static CCU_GATE_DEFINE(wdt_clk, "wdt_clk", CCU_PARENT_HW(pll1_d96_25p6), | ||
463 | + MPMU_WDTPCR, | ||
464 | + BIT(1), BIT(1), 0x0, | ||
465 | + 0); | ||
466 | + | ||
467 | +static CCU_GATE_DEFINE(ripc_clk, "ripc_clk", CCU_PARENT_NAME(vctcxo_24m), | ||
468 | + MPMU_RIPCCR, | ||
469 | + 0x3, 0x3, 0x0, | ||
470 | + 0); | ||
471 | + | ||
472 | +static CCU_GATE_FACTOR_DEFINE(i2s_sysclk, "i2s_sysclk", CCU_PARENT_HW(pll1_d16_153p6), | ||
473 | + MPMU_ISCCR, | ||
474 | + BIT(31), BIT(31), 0x0, 50, 1, | ||
475 | + 0); | ||
476 | +static CCU_GATE_FACTOR_DEFINE(i2s_bclk, "i2s_bclk", CCU_PARENT_HW(i2s_sysclk), | ||
477 | + MPMU_ISCCR, | ||
478 | + BIT(29), BIT(29), 0x0, 1, 1, | ||
479 | + 0); | ||
480 | + | ||
481 | +static const struct clk_parent_data apb_parents[] = { | ||
482 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
483 | + CCU_PARENT_HW(pll1_d48_51p2), | ||
484 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
485 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
486 | +}; | ||
487 | +static CCU_MUX_DEFINE(apb_clk, "apb_clk", apb_parents, | ||
488 | + MPMU_APBCSCR, | ||
489 | + 0, 2, | ||
490 | + 0); | ||
491 | + | ||
492 | +static CCU_GATE_DEFINE(wdt_bus_clk, "wdt_bus_clk", CCU_PARENT_HW(apb_clk), | ||
493 | + MPMU_WDTPCR, | ||
494 | + BIT(2), BIT(2), 0x0, | ||
495 | + 0); | ||
496 | +/* MPMU clocks end */ | ||
497 | + | ||
498 | +/* APBC clocks start */ | ||
499 | +static const struct clk_parent_data uart_clk_parents[] = { | ||
500 | + CCU_PARENT_HW(pll1_m3d128_57p6), | ||
501 | + CCU_PARENT_HW(slow_uart1_14p74), | ||
502 | + CCU_PARENT_HW(slow_uart2_48), | ||
503 | +}; | ||
504 | +static CCU_MUX_GATE_DEFINE(uart0_clk, "uart0_clk", uart_clk_parents, | ||
505 | + APBC_UART1_CLK_RST, | ||
506 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
507 | + CLK_IS_CRITICAL); | ||
508 | +static CCU_MUX_GATE_DEFINE(uart2_clk, "uart2_clk", uart_clk_parents, | ||
509 | + APBC_UART2_CLK_RST, | ||
510 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
511 | + 0); | ||
512 | +static CCU_MUX_GATE_DEFINE(uart3_clk, "uart3_clk", uart_clk_parents, | ||
513 | + APBC_UART3_CLK_RST, | ||
514 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
515 | + 0); | ||
516 | +static CCU_MUX_GATE_DEFINE(uart4_clk, "uart4_clk", uart_clk_parents, | ||
517 | + APBC_UART4_CLK_RST, | ||
518 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
519 | + 0); | ||
520 | +static CCU_MUX_GATE_DEFINE(uart5_clk, "uart5_clk", uart_clk_parents, | ||
521 | + APBC_UART5_CLK_RST, | ||
522 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
523 | + 0); | ||
524 | +static CCU_MUX_GATE_DEFINE(uart6_clk, "uart6_clk", uart_clk_parents, | ||
525 | + APBC_UART6_CLK_RST, | ||
526 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
527 | + 0); | ||
528 | +static CCU_MUX_GATE_DEFINE(uart7_clk, "uart7_clk", uart_clk_parents, | ||
529 | + APBC_UART7_CLK_RST, | ||
530 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
531 | + 0); | ||
532 | +static CCU_MUX_GATE_DEFINE(uart8_clk, "uart8_clk", uart_clk_parents, | ||
533 | + APBC_UART8_CLK_RST, | ||
534 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
535 | + 0); | ||
536 | +static CCU_MUX_GATE_DEFINE(uart9_clk, "uart9_clk", uart_clk_parents, | ||
537 | + APBC_UART9_CLK_RST, | ||
538 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
539 | + 0); | ||
540 | + | ||
541 | +static CCU_GATE_DEFINE(gpio_clk, "gpio_clk", CCU_PARENT_NAME(vctcxo_24m), | ||
542 | + APBC_GPIO_CLK_RST, | ||
543 | + BIT(1), BIT(1), 0x0, | ||
544 | + 0); | ||
545 | + | ||
546 | +static const struct clk_parent_data pwm_parents[] = { | ||
547 | + CCU_PARENT_HW(pll1_d192_12p8), | ||
548 | + CCU_PARENT_NAME(osc), | ||
549 | +}; | ||
550 | +static CCU_MUX_GATE_DEFINE(pwm0_clk, "pwm0_clk", pwm_parents, | ||
551 | + APBC_PWM0_CLK_RST, | ||
552 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
553 | + 0); | ||
554 | +static CCU_MUX_GATE_DEFINE(pwm1_clk, "pwm1_clk", pwm_parents, | ||
555 | + APBC_PWM1_CLK_RST, | ||
556 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
557 | + 0); | ||
558 | +static CCU_MUX_GATE_DEFINE(pwm2_clk, "pwm2_clk", pwm_parents, | ||
559 | + APBC_PWM2_CLK_RST, | ||
560 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
561 | + 0); | ||
562 | +static CCU_MUX_GATE_DEFINE(pwm3_clk, "pwm3_clk", pwm_parents, | ||
563 | + APBC_PWM3_CLK_RST, | ||
564 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
565 | + 0); | ||
566 | +static CCU_MUX_GATE_DEFINE(pwm4_clk, "pwm4_clk", pwm_parents, | ||
567 | + APBC_PWM4_CLK_RST, | ||
568 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
569 | + 0); | ||
570 | +static CCU_MUX_GATE_DEFINE(pwm5_clk, "pwm5_clk", pwm_parents, | ||
571 | + APBC_PWM5_CLK_RST, | ||
572 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
573 | + 0); | ||
574 | +static CCU_MUX_GATE_DEFINE(pwm6_clk, "pwm6_clk", pwm_parents, | ||
575 | + APBC_PWM6_CLK_RST, | ||
576 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
577 | + 0); | ||
578 | +static CCU_MUX_GATE_DEFINE(pwm7_clk, "pwm7_clk", pwm_parents, | ||
579 | + APBC_PWM7_CLK_RST, | ||
580 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
581 | + 0); | ||
582 | +static CCU_MUX_GATE_DEFINE(pwm8_clk, "pwm8_clk", pwm_parents, | ||
583 | + APBC_PWM8_CLK_RST, | ||
584 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
585 | + 0); | ||
586 | +static CCU_MUX_GATE_DEFINE(pwm9_clk, "pwm9_clk", pwm_parents, | ||
587 | + APBC_PWM9_CLK_RST, | ||
588 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
589 | + 0); | ||
590 | +static CCU_MUX_GATE_DEFINE(pwm10_clk, "pwm10_clk", pwm_parents, | ||
591 | + APBC_PWM10_CLK_RST, | ||
592 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
593 | + 0); | ||
594 | +static CCU_MUX_GATE_DEFINE(pwm11_clk, "pwm11_clk", pwm_parents, | ||
595 | + APBC_PWM11_CLK_RST, | ||
596 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
597 | + 0); | ||
598 | +static CCU_MUX_GATE_DEFINE(pwm12_clk, "pwm12_clk", pwm_parents, | ||
599 | + APBC_PWM12_CLK_RST, | ||
600 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
601 | + 0); | ||
602 | +static CCU_MUX_GATE_DEFINE(pwm13_clk, "pwm13_clk", pwm_parents, | ||
603 | + APBC_PWM13_CLK_RST, | ||
604 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
605 | + 0); | ||
606 | +static CCU_MUX_GATE_DEFINE(pwm14_clk, "pwm14_clk", pwm_parents, | ||
607 | + APBC_PWM14_CLK_RST, | ||
608 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
609 | + 0); | ||
610 | +static CCU_MUX_GATE_DEFINE(pwm15_clk, "pwm15_clk", pwm_parents, | ||
611 | + APBC_PWM15_CLK_RST, | ||
612 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
613 | + 0); | ||
614 | +static CCU_MUX_GATE_DEFINE(pwm16_clk, "pwm16_clk", pwm_parents, | ||
615 | + APBC_PWM16_CLK_RST, | ||
616 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
617 | + 0); | ||
618 | +static CCU_MUX_GATE_DEFINE(pwm17_clk, "pwm17_clk", pwm_parents, | ||
619 | + APBC_PWM17_CLK_RST, | ||
620 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
621 | + 0); | ||
622 | +static CCU_MUX_GATE_DEFINE(pwm18_clk, "pwm18_clk", pwm_parents, | ||
623 | + APBC_PWM18_CLK_RST, | ||
624 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
625 | + 0); | ||
626 | +static CCU_MUX_GATE_DEFINE(pwm19_clk, "pwm19_clk", pwm_parents, | ||
627 | + APBC_PWM19_CLK_RST, | ||
628 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
629 | + 0); | ||
630 | + | ||
631 | +static const struct clk_parent_data ssp_parents[] = { | ||
632 | + CCU_PARENT_HW(pll1_d384_6p4), | ||
633 | + CCU_PARENT_HW(pll1_d192_12p8), | ||
634 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
635 | + CCU_PARENT_HW(pll1_d48_51p2), | ||
636 | + CCU_PARENT_HW(pll1_d768_3p2), | ||
637 | + CCU_PARENT_HW(pll1_d1536_1p6), | ||
638 | + CCU_PARENT_HW(pll1_d3072_0p8), | ||
639 | +}; | ||
640 | +static CCU_MUX_GATE_DEFINE(ssp3_clk, "ssp3_clk", ssp_parents, | ||
641 | + APBC_SSP3_CLK_RST, | ||
642 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
643 | + 0); | ||
644 | + | ||
645 | +static CCU_GATE_DEFINE(rtc_clk, "rtc_clk", CCU_PARENT_NAME(osc), | ||
646 | + APBC_RTC_CLK_RST, | ||
647 | + 0x82, 0x82, 0x0, | ||
648 | + 0); | ||
649 | + | ||
650 | +static const struct clk_parent_data twsi_parents[] = { | ||
651 | + CCU_PARENT_HW(pll1_d78_31p5), | ||
652 | + CCU_PARENT_HW(pll1_d48_51p2), | ||
653 | + CCU_PARENT_HW(pll1_d40_61p44), | ||
654 | +}; | ||
655 | +static CCU_MUX_GATE_DEFINE(twsi0_clk, "twsi0_clk", twsi_parents, | ||
656 | + APBC_TWSI0_CLK_RST, | ||
657 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
658 | + 0); | ||
659 | +static CCU_MUX_GATE_DEFINE(twsi1_clk, "twsi1_clk", twsi_parents, | ||
660 | + APBC_TWSI1_CLK_RST, | ||
661 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
662 | + 0); | ||
663 | +static CCU_MUX_GATE_DEFINE(twsi2_clk, "twsi2_clk", twsi_parents, | ||
664 | + APBC_TWSI2_CLK_RST, | ||
665 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
666 | + 0); | ||
667 | +static CCU_MUX_GATE_DEFINE(twsi4_clk, "twsi4_clk", twsi_parents, | ||
668 | + APBC_TWSI4_CLK_RST, | ||
669 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
670 | + 0); | ||
671 | +static CCU_MUX_GATE_DEFINE(twsi5_clk, "twsi5_clk", twsi_parents, | ||
672 | + APBC_TWSI5_CLK_RST, | ||
673 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
674 | + 0); | ||
675 | +static CCU_MUX_GATE_DEFINE(twsi6_clk, "twsi6_clk", twsi_parents, | ||
676 | + APBC_TWSI6_CLK_RST, | ||
677 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
678 | + 0); | ||
679 | +static CCU_MUX_GATE_DEFINE(twsi7_clk, "twsi7_clk", twsi_parents, | ||
680 | + APBC_TWSI7_CLK_RST, | ||
681 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
682 | + 0); | ||
683 | +static CCU_MUX_GATE_DEFINE(twsi8_clk, "twsi8_clk", twsi_parents, | ||
684 | + APBC_TWSI8_CLK_RST, | ||
685 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
686 | + 0); | ||
687 | + | ||
688 | +static const struct clk_parent_data timer_parents[] = { | ||
689 | + CCU_PARENT_HW(pll1_d192_12p8), | ||
690 | + CCU_PARENT_NAME(osc), | ||
691 | + CCU_PARENT_HW(pll1_d384_6p4), | ||
692 | + CCU_PARENT_NAME(vctcxo_3m), | ||
693 | + CCU_PARENT_NAME(vctcxo_1m), | ||
694 | +}; | ||
695 | +static CCU_MUX_GATE_DEFINE(timers1_clk, "timers1_clk", timer_parents, | ||
696 | + APBC_TIMERS1_CLK_RST, | ||
697 | + 4, 3, 0x3, 0x3, 0x0, | ||
698 | + 0); | ||
699 | +static CCU_MUX_GATE_DEFINE(timers2_clk, "timers2_clk", timer_parents, | ||
700 | + APBC_TIMERS2_CLK_RST, | ||
701 | + 4, 3, 0x3, 0x3, 0x0, | ||
702 | + 0); | ||
703 | + | ||
704 | +static CCU_GATE_DEFINE(aib_clk, "aib_clk", CCU_PARENT_NAME(vctcxo_24m), | ||
705 | + APBC_AIB_CLK_RST, | ||
706 | + BIT(1), BIT(1), 0x0, | ||
707 | + 0); | ||
708 | + | ||
709 | +static CCU_GATE_DEFINE(onewire_clk, "onewire_clk", CCU_PARENT_NAME(vctcxo_24m), | ||
710 | + APBC_ONEWIRE_CLK_RST, | ||
711 | + BIT(1), BIT(1), 0x0, | ||
712 | + 0); | ||
713 | + | ||
714 | +static const struct clk_parent_data sspa_parents[] = { | ||
715 | + CCU_PARENT_HW(pll1_d384_6p4), | ||
716 | + CCU_PARENT_HW(pll1_d192_12p8), | ||
717 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
718 | + CCU_PARENT_HW(pll1_d48_51p2), | ||
719 | + CCU_PARENT_HW(pll1_d768_3p2), | ||
720 | + CCU_PARENT_HW(pll1_d1536_1p6), | ||
721 | + CCU_PARENT_HW(pll1_d3072_0p8), | ||
722 | + CCU_PARENT_HW(i2s_bclk), | ||
723 | +}; | ||
724 | +static CCU_MUX_GATE_DEFINE(sspa0_clk, "sspa0_clk", sspa_parents, | ||
725 | + APBC_SSPA0_CLK_RST, | ||
726 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
727 | + 0); | ||
728 | +static CCU_MUX_GATE_DEFINE(sspa1_clk, "sspa1_clk", sspa_parents, | ||
729 | + APBC_SSPA1_CLK_RST, | ||
730 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
731 | + 0); | ||
732 | +static CCU_GATE_DEFINE(dro_clk, "dro_clk", CCU_PARENT_HW(apb_clk), | ||
733 | + APBC_DRO_CLK_RST, | ||
734 | + BIT(1), BIT(1), 0x0, | ||
735 | + 0); | ||
736 | +static CCU_GATE_DEFINE(ir_clk, "ir_clk", CCU_PARENT_HW(apb_clk), | ||
737 | + APBC_IR_CLK_RST, | ||
738 | + BIT(1), BIT(1), 0x0, | ||
739 | + 0); | ||
740 | +static CCU_GATE_DEFINE(tsen_clk, "tsen_clk", CCU_PARENT_HW(apb_clk), | ||
741 | + APBC_TSEN_CLK_RST, | ||
742 | + BIT(1), BIT(1), 0x0, | ||
743 | + 0); | ||
744 | +static CCU_GATE_DEFINE(ipc_ap2aud_clk, "ipc_ap2aud_clk", CCU_PARENT_HW(apb_clk), | ||
745 | + APBC_IPC_AP2AUD_CLK_RST, | ||
746 | + BIT(1), BIT(1), 0x0, | ||
747 | + 0); | ||
748 | + | ||
749 | +static const struct clk_parent_data can_parents[] = { | ||
750 | + CCU_PARENT_HW(pll3_20), | ||
751 | + CCU_PARENT_HW(pll3_40), | ||
752 | + CCU_PARENT_HW(pll3_80), | ||
753 | +}; | ||
754 | +static CCU_MUX_GATE_DEFINE(can0_clk, "can0_clk", can_parents, | ||
755 | + APBC_CAN0_CLK_RST, | ||
756 | + 4, 3, BIT(1), BIT(1), 0x0, | ||
757 | + 0); | ||
758 | +static CCU_GATE_DEFINE(can0_bus_clk, "can0_bus_clk", CCU_PARENT_NAME(vctcxo_24m), | ||
759 | + APBC_CAN0_CLK_RST, | ||
760 | + BIT(0), BIT(0), 0x0, | ||
761 | + 0); | ||
762 | + | ||
763 | +static CCU_GATE_DEFINE(uart0_bus_clk, "uart0_bus_clk", CCU_PARENT_HW(apb_clk), | ||
764 | + APBC_UART1_CLK_RST, | ||
765 | + BIT(0), BIT(0), 0x0, | ||
766 | + CLK_IS_CRITICAL); | ||
767 | +static CCU_GATE_DEFINE(uart2_bus_clk, "uart2_bus_clk", CCU_PARENT_HW(apb_clk), | ||
768 | + APBC_UART2_CLK_RST, | ||
769 | + BIT(0), BIT(0), 0x0, | ||
770 | + 0); | ||
771 | +static CCU_GATE_DEFINE(uart3_bus_clk, "uart3_bus_clk", CCU_PARENT_HW(apb_clk), | ||
772 | + APBC_UART3_CLK_RST, | ||
773 | + BIT(0), BIT(0), 0x0, | ||
774 | + 0); | ||
775 | +static CCU_GATE_DEFINE(uart4_bus_clk, "uart4_bus_clk", CCU_PARENT_HW(apb_clk), | ||
776 | + APBC_UART4_CLK_RST, | ||
777 | + BIT(0), BIT(0), 0x0, | ||
778 | + 0); | ||
779 | +static CCU_GATE_DEFINE(uart5_bus_clk, "uart5_bus_clk", CCU_PARENT_HW(apb_clk), | ||
780 | + APBC_UART5_CLK_RST, | ||
781 | + BIT(0), BIT(0), 0x0, | ||
782 | + 0); | ||
783 | +static CCU_GATE_DEFINE(uart6_bus_clk, "uart6_bus_clk", CCU_PARENT_HW(apb_clk), | ||
784 | + APBC_UART6_CLK_RST, | ||
785 | + BIT(0), BIT(0), 0x0, | ||
786 | + 0); | ||
787 | +static CCU_GATE_DEFINE(uart7_bus_clk, "uart7_bus_clk", CCU_PARENT_HW(apb_clk), | ||
788 | + APBC_UART7_CLK_RST, | ||
789 | + BIT(0), BIT(0), 0x0, | ||
790 | + 0); | ||
791 | +static CCU_GATE_DEFINE(uart8_bus_clk, "uart8_bus_clk", CCU_PARENT_HW(apb_clk), | ||
792 | + APBC_UART8_CLK_RST, | ||
793 | + BIT(0), BIT(0), 0x0, | ||
794 | + 0); | ||
795 | +static CCU_GATE_DEFINE(uart9_bus_clk, "uart9_bus_clk", CCU_PARENT_HW(apb_clk), | ||
796 | + APBC_UART9_CLK_RST, | ||
797 | + BIT(0), BIT(0), 0x0, | ||
798 | + 0); | ||
799 | + | ||
800 | +static CCU_GATE_DEFINE(gpio_bus_clk, "gpio_bus_clk", CCU_PARENT_HW(apb_clk), | ||
801 | + APBC_GPIO_CLK_RST, | ||
802 | + BIT(0), BIT(0), 0x0, | ||
803 | + 0); | ||
804 | + | ||
805 | +static CCU_GATE_DEFINE(pwm0_bus_clk, "pwm0_bus_clk", CCU_PARENT_HW(apb_clk), | ||
806 | + APBC_PWM0_CLK_RST, | ||
807 | + BIT(0), BIT(0), 0x0, | ||
808 | + 0); | ||
809 | +static CCU_GATE_DEFINE(pwm1_bus_clk, "pwm1_bus_clk", CCU_PARENT_HW(apb_clk), | ||
810 | + APBC_PWM1_CLK_RST, | ||
811 | + BIT(0), BIT(0), 0x0, | ||
812 | + 0); | ||
813 | +static CCU_GATE_DEFINE(pwm2_bus_clk, "pwm2_bus_clk", CCU_PARENT_HW(apb_clk), | ||
814 | + APBC_PWM2_CLK_RST, | ||
815 | + BIT(0), BIT(0), 0x0, | ||
816 | + 0); | ||
817 | +static CCU_GATE_DEFINE(pwm3_bus_clk, "pwm3_bus_clk", CCU_PARENT_HW(apb_clk), | ||
818 | + APBC_PWM3_CLK_RST, | ||
819 | + BIT(0), BIT(0), 0x0, | ||
820 | + 0); | ||
821 | +static CCU_GATE_DEFINE(pwm4_bus_clk, "pwm4_bus_clk", CCU_PARENT_HW(apb_clk), | ||
822 | + APBC_PWM4_CLK_RST, | ||
823 | + BIT(0), BIT(0), 0x0, | ||
824 | + 0); | ||
825 | +static CCU_GATE_DEFINE(pwm5_bus_clk, "pwm5_bus_clk", CCU_PARENT_HW(apb_clk), | ||
826 | + APBC_PWM5_CLK_RST, | ||
827 | + BIT(0), BIT(0), 0x0, | ||
828 | + 0); | ||
829 | +static CCU_GATE_DEFINE(pwm6_bus_clk, "pwm6_bus_clk", CCU_PARENT_HW(apb_clk), | ||
830 | + APBC_PWM6_CLK_RST, | ||
831 | + BIT(0), BIT(0), 0x0, | ||
832 | + 0); | ||
833 | +static CCU_GATE_DEFINE(pwm7_bus_clk, "pwm7_bus_clk", CCU_PARENT_HW(apb_clk), | ||
834 | + APBC_PWM7_CLK_RST, | ||
835 | + BIT(0), BIT(0), 0x0, | ||
836 | + 0); | ||
837 | +static CCU_GATE_DEFINE(pwm8_bus_clk, "pwm8_bus_clk", CCU_PARENT_HW(apb_clk), | ||
838 | + APBC_PWM8_CLK_RST, | ||
839 | + BIT(0), BIT(0), 0x0, | ||
840 | + 0); | ||
841 | +static CCU_GATE_DEFINE(pwm9_bus_clk, "pwm9_bus_clk", CCU_PARENT_HW(apb_clk), | ||
842 | + APBC_PWM9_CLK_RST, | ||
843 | + BIT(0), BIT(0), 0x0, | ||
844 | + 0); | ||
845 | +static CCU_GATE_DEFINE(pwm10_bus_clk, "pwm10_bus_clk", CCU_PARENT_HW(apb_clk), | ||
846 | + APBC_PWM10_CLK_RST, | ||
847 | + BIT(0), BIT(0), 0x0, | ||
848 | + 0); | ||
849 | +static CCU_GATE_DEFINE(pwm11_bus_clk, "pwm11_bus_clk", CCU_PARENT_HW(apb_clk), | ||
850 | + APBC_PWM11_CLK_RST, | ||
851 | + BIT(0), BIT(0), 0x0, | ||
852 | + 0); | ||
853 | +static CCU_GATE_DEFINE(pwm12_bus_clk, "pwm12_bus_clk", CCU_PARENT_HW(apb_clk), | ||
854 | + APBC_PWM12_CLK_RST, | ||
855 | + BIT(0), BIT(0), 0x0, | ||
856 | + 0); | ||
857 | +static CCU_GATE_DEFINE(pwm13_bus_clk, "pwm13_bus_clk", CCU_PARENT_HW(apb_clk), | ||
858 | + APBC_PWM13_CLK_RST, | ||
859 | + BIT(0), BIT(0), 0x0, | ||
860 | + 0); | ||
861 | +static CCU_GATE_DEFINE(pwm14_bus_clk, "pwm14_bus_clk", CCU_PARENT_HW(apb_clk), | ||
862 | + APBC_PWM14_CLK_RST, | ||
863 | + BIT(0), BIT(0), 0x0, | ||
864 | + 0); | ||
865 | +static CCU_GATE_DEFINE(pwm15_bus_clk, "pwm15_bus_clk", CCU_PARENT_HW(apb_clk), | ||
866 | + APBC_PWM15_CLK_RST, | ||
867 | + BIT(0), BIT(0), 0x0, | ||
868 | + 0); | ||
869 | +static CCU_GATE_DEFINE(pwm16_bus_clk, "pwm16_bus_clk", CCU_PARENT_HW(apb_clk), | ||
870 | + APBC_PWM16_CLK_RST, | ||
871 | + BIT(0), BIT(0), 0x0, | ||
872 | + 0); | ||
873 | +static CCU_GATE_DEFINE(pwm17_bus_clk, "pwm17_bus_clk", CCU_PARENT_HW(apb_clk), | ||
874 | + APBC_PWM17_CLK_RST, | ||
875 | + BIT(0), BIT(0), 0x0, | ||
876 | + 0); | ||
877 | +static CCU_GATE_DEFINE(pwm18_bus_clk, "pwm18_bus_clk", CCU_PARENT_HW(apb_clk), | ||
878 | + APBC_PWM18_CLK_RST, | ||
879 | + BIT(0), BIT(0), 0x0, | ||
880 | + 0); | ||
881 | +static CCU_GATE_DEFINE(pwm19_bus_clk, "pwm19_bus_clk", CCU_PARENT_HW(apb_clk), | ||
882 | + APBC_PWM19_CLK_RST, | ||
883 | + BIT(0), BIT(0), 0x0, | ||
884 | + 0); | ||
885 | + | ||
886 | +static CCU_GATE_DEFINE(ssp3_bus_clk, "ssp3_bus_clk", CCU_PARENT_HW(apb_clk), | ||
887 | + APBC_SSP3_CLK_RST, | ||
888 | + BIT(0), BIT(0), 0x0, | ||
889 | + 0); | ||
890 | + | ||
891 | +static CCU_GATE_DEFINE(rtc_bus_clk, "rtc_bus_clk", CCU_PARENT_HW(apb_clk), | ||
892 | + APBC_RTC_CLK_RST, | ||
893 | + BIT(0), BIT(0), 0x0, | ||
894 | + 0); | ||
895 | + | ||
896 | +static CCU_GATE_DEFINE(twsi0_bus_clk, "twsi0_bus_clk", CCU_PARENT_HW(apb_clk), | ||
897 | + APBC_TWSI0_CLK_RST, | ||
898 | + BIT(0), BIT(0), 0x0, | ||
899 | + 0); | ||
900 | +static CCU_GATE_DEFINE(twsi1_bus_clk, "twsi1_bus_clk", CCU_PARENT_HW(apb_clk), | ||
901 | + APBC_TWSI1_CLK_RST, | ||
902 | + BIT(0), BIT(0), 0x0, | ||
903 | + 0); | ||
904 | +static CCU_GATE_DEFINE(twsi2_bus_clk, "twsi2_bus_clk", CCU_PARENT_HW(apb_clk), | ||
905 | + APBC_TWSI2_CLK_RST, | ||
906 | + BIT(0), BIT(0), 0x0, | ||
907 | + 0); | ||
908 | +static CCU_GATE_DEFINE(twsi4_bus_clk, "twsi4_bus_clk", CCU_PARENT_HW(apb_clk), | ||
909 | + APBC_TWSI4_CLK_RST, | ||
910 | + BIT(0), BIT(0), 0x0, | ||
911 | + 0); | ||
912 | +static CCU_GATE_DEFINE(twsi5_bus_clk, "twsi5_bus_clk", CCU_PARENT_HW(apb_clk), | ||
913 | + APBC_TWSI5_CLK_RST, | ||
914 | + BIT(0), BIT(0), 0x0, | ||
915 | + 0); | ||
916 | +static CCU_GATE_DEFINE(twsi6_bus_clk, "twsi6_bus_clk", CCU_PARENT_HW(apb_clk), | ||
917 | + APBC_TWSI6_CLK_RST, | ||
918 | + BIT(0), BIT(0), 0x0, | ||
919 | + 0); | ||
920 | +static CCU_GATE_DEFINE(twsi7_bus_clk, "twsi7_bus_clk", CCU_PARENT_HW(apb_clk), | ||
921 | + APBC_TWSI7_CLK_RST, | ||
922 | + BIT(0), BIT(0), 0x0, | ||
923 | + 0); | ||
924 | +static CCU_GATE_DEFINE(twsi8_bus_clk, "twsi8_bus_clk", CCU_PARENT_HW(apb_clk), | ||
925 | + APBC_TWSI8_CLK_RST, | ||
926 | + BIT(0), BIT(0), 0x0, | ||
927 | + 0); | ||
928 | + | ||
929 | +static CCU_GATE_DEFINE(timers1_bus_clk, "timers1_bus_clk", CCU_PARENT_HW(apb_clk), | ||
930 | + APBC_TIMERS1_CLK_RST, | ||
931 | + BIT(0), BIT(0), 0x0, | ||
932 | + 0); | ||
933 | +static CCU_GATE_DEFINE(timers2_bus_clk, "timers2_bus_clk", CCU_PARENT_HW(apb_clk), | ||
934 | + APBC_TIMERS2_CLK_RST, | ||
935 | + BIT(0), BIT(0), 0x0, | ||
936 | + 0); | ||
937 | + | ||
938 | +static CCU_GATE_DEFINE(aib_bus_clk, "aib_bus_clk", CCU_PARENT_HW(apb_clk), | ||
939 | + APBC_AIB_CLK_RST, | ||
940 | + BIT(0), BIT(0), 0x0, | ||
941 | + 0); | ||
942 | + | ||
943 | +static CCU_GATE_DEFINE(onewire_bus_clk, "onewire_bus_clk", CCU_PARENT_HW(apb_clk), | ||
944 | + APBC_ONEWIRE_CLK_RST, | ||
945 | + BIT(0), BIT(0), 0x0, | ||
946 | + 0); | ||
947 | + | ||
948 | +static CCU_GATE_DEFINE(sspa0_bus_clk, "sspa0_bus_clk", CCU_PARENT_HW(apb_clk), | ||
949 | + APBC_SSPA0_CLK_RST, | ||
950 | + BIT(0), BIT(0), 0x0, | ||
951 | + 0); | ||
952 | +static CCU_GATE_DEFINE(sspa1_bus_clk, "sspa1_bus_clk", CCU_PARENT_HW(apb_clk), | ||
953 | + APBC_SSPA1_CLK_RST, | ||
954 | + BIT(0), BIT(0), 0x0, | ||
955 | + 0); | ||
956 | + | ||
957 | +static CCU_GATE_DEFINE(tsen_bus_clk, "tsen_bus_clk", CCU_PARENT_HW(apb_clk), | ||
958 | + APBC_TSEN_CLK_RST, | ||
959 | + BIT(0), BIT(0), 0x0, | ||
960 | + 0); | ||
961 | + | ||
962 | +static CCU_GATE_DEFINE(ipc_ap2aud_bus_clk, "ipc_ap2aud_bus_clk", CCU_PARENT_HW(apb_clk), | ||
963 | + APBC_IPC_AP2AUD_CLK_RST, | ||
964 | + BIT(0), BIT(0), 0x0, | ||
965 | + 0); | ||
966 | +/* APBC clocks end */ | ||
967 | + | ||
968 | +/* APMU clocks start */ | ||
969 | +static const struct clk_parent_data pmua_aclk_parents[] = { | ||
970 | + CCU_PARENT_HW(pll1_d10_245p76), | ||
971 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
972 | +}; | ||
973 | +static CCU_DIV_FC_MUX_DEFINE(pmua_aclk, "pmua_aclk", pmua_aclk_parents, | ||
974 | + APMU_ACLK_CLK_CTRL, | ||
975 | + 1, 2, BIT(4), | ||
976 | + 0, 1, | ||
977 | + 0); | ||
978 | + | ||
979 | +static const struct clk_parent_data cci550_clk_parents[] = { | ||
980 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
981 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
982 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
983 | + CCU_PARENT_HW(pll2_d3), | ||
984 | +}; | ||
985 | +static CCU_DIV_FC_MUX_DEFINE(cci550_clk, "cci550_clk", cci550_clk_parents, | ||
986 | + APMU_CCI550_CLK_CTRL, | ||
987 | + 8, 3, BIT(12), 0, 2, CLK_IS_CRITICAL); | ||
988 | + | ||
989 | +static const struct clk_parent_data cpu_c0_hi_clk_parents[] = { | ||
990 | + CCU_PARENT_HW(pll3_d2), | ||
991 | + CCU_PARENT_HW(pll3_d1), | ||
992 | +}; | ||
993 | +static CCU_MUX_DEFINE(cpu_c0_hi_clk, "cpu_c0_hi_clk", cpu_c0_hi_clk_parents, | ||
994 | + APMU_CPU_C0_CLK_CTRL, | ||
995 | + 13, 1, 0); | ||
996 | +static const struct clk_parent_data cpu_c0_clk_parents[] = { | ||
997 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
998 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
999 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1000 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1001 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
1002 | + CCU_PARENT_HW(pll3_d3), | ||
1003 | + CCU_PARENT_HW(pll2_d3), | ||
1004 | + CCU_PARENT_HW(cpu_c0_hi_clk), | ||
1005 | +}; | ||
1006 | +static CCU_MUX_FC_DEFINE(cpu_c0_core_clk, "cpu_c0_core_clk", cpu_c0_clk_parents, | ||
1007 | + APMU_CPU_C0_CLK_CTRL, | ||
1008 | + BIT(12), 0, 3, CLK_IS_CRITICAL); | ||
1009 | +static CCU_DIV_DEFINE(cpu_c0_ace_clk, "cpu_c0_ace_clk", CCU_PARENT_HW(cpu_c0_core_clk), | ||
1010 | + APMU_CPU_C0_CLK_CTRL, | ||
1011 | + 6, 3, CLK_IS_CRITICAL); | ||
1012 | +static CCU_DIV_DEFINE(cpu_c0_tcm_clk, "cpu_c0_tcm_clk", CCU_PARENT_HW(cpu_c0_core_clk), | ||
1013 | + APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL); | ||
1014 | + | ||
1015 | +static const struct clk_parent_data cpu_c1_hi_clk_parents[] = { | ||
1016 | + CCU_PARENT_HW(pll3_d2), | ||
1017 | + CCU_PARENT_HW(pll3_d1), | ||
1018 | +}; | ||
1019 | +static CCU_MUX_DEFINE(cpu_c1_hi_clk, "cpu_c1_hi_clk", cpu_c1_hi_clk_parents, | ||
1020 | + APMU_CPU_C1_CLK_CTRL, | ||
1021 | + 13, 1, CLK_IS_CRITICAL); | ||
1022 | +static const struct clk_parent_data cpu_c1_clk_parents[] = { | ||
1023 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1024 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1025 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1026 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1027 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
1028 | + CCU_PARENT_HW(pll3_d3), | ||
1029 | + CCU_PARENT_HW(pll2_d3), | ||
1030 | + CCU_PARENT_HW(cpu_c1_hi_clk), | ||
1031 | +}; | ||
1032 | +static CCU_MUX_FC_DEFINE(cpu_c1_core_clk, "cpu_c1_core_clk", cpu_c1_clk_parents, | ||
1033 | + APMU_CPU_C1_CLK_CTRL, | ||
1034 | + BIT(12), 0, 3, CLK_IS_CRITICAL); | ||
1035 | +static CCU_DIV_DEFINE(cpu_c1_ace_clk, "cpu_c1_ace_clk", CCU_PARENT_HW(cpu_c1_core_clk), | ||
1036 | + APMU_CPU_C1_CLK_CTRL, | ||
1037 | + 6, 3, CLK_IS_CRITICAL); | ||
1038 | + | ||
1039 | +static const struct clk_parent_data jpg_parents[] = { | ||
1040 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1041 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1042 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1043 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1044 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
1045 | + CCU_PARENT_HW(pll2_d4), | ||
1046 | + CCU_PARENT_HW(pll2_d3), | ||
1047 | +}; | ||
1048 | +static CCU_DIV_FC_MUX_GATE_DEFINE(jpg_clk, "jpg_clk", jpg_parents, | ||
1049 | + APMU_JPG_CLK_RES_CTRL, | ||
1050 | + 5, 3, BIT(15), | ||
1051 | + 2, 3, BIT(1), BIT(1), 0x0, | ||
1052 | + 0); | ||
1053 | + | ||
1054 | +static const struct clk_parent_data ccic2phy_parents[] = { | ||
1055 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
1056 | + CCU_PARENT_HW(pll1_d48_51p2_ap), | ||
1057 | +}; | ||
1058 | +static CCU_MUX_GATE_DEFINE(ccic2phy_clk, "ccic2phy_clk", ccic2phy_parents, | ||
1059 | + APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
1060 | + 7, 1, BIT(5), BIT(5), 0x0, | ||
1061 | + 0); | ||
1062 | + | ||
1063 | +static const struct clk_parent_data ccic3phy_parents[] = { | ||
1064 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
1065 | + CCU_PARENT_HW(pll1_d48_51p2_ap), | ||
1066 | +}; | ||
1067 | +static CCU_MUX_GATE_DEFINE(ccic3phy_clk, "ccic3phy_clk", ccic3phy_parents, | ||
1068 | + APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
1069 | + 31, 1, BIT(30), BIT(30), 0x0, | ||
1070 | + 0); | ||
1071 | + | ||
1072 | +static const struct clk_parent_data csi_parents[] = { | ||
1073 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1074 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1075 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1076 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1077 | + CCU_PARENT_HW(pll2_d2), | ||
1078 | + CCU_PARENT_HW(pll2_d3), | ||
1079 | + CCU_PARENT_HW(pll2_d4), | ||
1080 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
1081 | +}; | ||
1082 | +static CCU_DIV_FC_MUX_GATE_DEFINE(csi_clk, "csi_clk", csi_parents, | ||
1083 | + APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
1084 | + 20, 3, BIT(15), | ||
1085 | + 16, 3, BIT(4), BIT(4), 0x0, | ||
1086 | + 0); | ||
1087 | + | ||
1088 | +static const struct clk_parent_data camm_parents[] = { | ||
1089 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1090 | + CCU_PARENT_HW(pll2_d5), | ||
1091 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1092 | + CCU_PARENT_NAME(vctcxo_24m), | ||
1093 | +}; | ||
1094 | +static CCU_DIV_MUX_GATE_DEFINE(camm0_clk, "camm0_clk", camm_parents, | ||
1095 | + APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
1096 | + 23, 4, 8, 2, | ||
1097 | + BIT(28), BIT(28), 0x0, | ||
1098 | + 0); | ||
1099 | +static CCU_DIV_MUX_GATE_DEFINE(camm1_clk, "camm1_clk", camm_parents, | ||
1100 | + APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
1101 | + 23, 4, 8, 2, BIT(6), BIT(6), 0x0, | ||
1102 | + 0); | ||
1103 | +static CCU_DIV_MUX_GATE_DEFINE(camm2_clk, "camm2_clk", camm_parents, | ||
1104 | + APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
1105 | + 23, 4, 8, 2, BIT(3), BIT(3), 0x0, | ||
1106 | + 0); | ||
1107 | + | ||
1108 | +static const struct clk_parent_data isp_cpp_parents[] = { | ||
1109 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1110 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1111 | +}; | ||
1112 | +static CCU_DIV_MUX_GATE_DEFINE(isp_cpp_clk, "isp_cpp_clk", isp_cpp_parents, | ||
1113 | + APMU_ISP_CLK_RES_CTRL, | ||
1114 | + 24, 2, 26, 1, BIT(28), BIT(28), 0x0, | ||
1115 | + 0); | ||
1116 | +static const struct clk_parent_data isp_bus_parents[] = { | ||
1117 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1118 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1119 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1120 | + CCU_PARENT_HW(pll1_d10_245p76), | ||
1121 | +}; | ||
1122 | +static CCU_DIV_FC_MUX_GATE_DEFINE(isp_bus_clk, "isp_bus_clk", isp_bus_parents, | ||
1123 | + APMU_ISP_CLK_RES_CTRL, | ||
1124 | + 18, 3, BIT(23), | ||
1125 | + 21, 2, BIT(17), BIT(17), 0x0, | ||
1126 | + 0); | ||
1127 | +static const struct clk_parent_data isp_parents[] = { | ||
1128 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1129 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1130 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1131 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1132 | +}; | ||
1133 | +static CCU_DIV_FC_MUX_GATE_DEFINE(isp_clk, "isp_clk", isp_parents, | ||
1134 | + APMU_ISP_CLK_RES_CTRL, | ||
1135 | + 4, 3, BIT(7), | ||
1136 | + 8, 2, BIT(1), BIT(1), 0x0, | ||
1137 | + 0); | ||
1138 | + | ||
1139 | +static const struct clk_parent_data dpumclk_parents[] = { | ||
1140 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1141 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1142 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1143 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1144 | +}; | ||
1145 | +static CCU_DIV2_FC_MUX_GATE_DEFINE(dpu_mclk, "dpu_mclk", dpumclk_parents, | ||
1146 | + APMU_LCD_CLK_RES_CTRL2, | ||
1147 | + APMU_LCD_CLK_RES_CTRL1, | ||
1148 | + 1, 4, BIT(29), | ||
1149 | + 5, 3, BIT(0), BIT(0), 0x0, | ||
1150 | + 0); | ||
1151 | + | ||
1152 | +static const struct clk_parent_data dpuesc_parents[] = { | ||
1153 | + CCU_PARENT_HW(pll1_d48_51p2_ap), | ||
1154 | + CCU_PARENT_HW(pll1_d52_47p26), | ||
1155 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
1156 | + CCU_PARENT_HW(pll1_d32_76p8), | ||
1157 | +}; | ||
1158 | +static CCU_MUX_GATE_DEFINE(dpu_esc_clk, "dpu_esc_clk", dpuesc_parents, | ||
1159 | + APMU_LCD_CLK_RES_CTRL1, | ||
1160 | + 0, 2, BIT(2), BIT(2), 0x0, | ||
1161 | + 0); | ||
1162 | + | ||
1163 | +static const struct clk_parent_data dpubit_parents[] = { | ||
1164 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1165 | + CCU_PARENT_HW(pll2_d2), | ||
1166 | + CCU_PARENT_HW(pll2_d3), | ||
1167 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
1168 | + CCU_PARENT_HW(pll2_d4), | ||
1169 | + CCU_PARENT_HW(pll2_d5), | ||
1170 | + CCU_PARENT_HW(pll2_d8), | ||
1171 | + CCU_PARENT_HW(pll2_d8), | ||
1172 | +}; | ||
1173 | +static CCU_DIV_FC_MUX_GATE_DEFINE(dpu_bit_clk, "dpu_bit_clk", dpubit_parents, | ||
1174 | + APMU_LCD_CLK_RES_CTRL1, | ||
1175 | + 17, 3, BIT(31), | ||
1176 | + 20, 3, BIT(16), BIT(16), 0x0, | ||
1177 | + 0); | ||
1178 | + | ||
1179 | +static const struct clk_parent_data dpupx_parents[] = { | ||
1180 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1181 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1182 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1183 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1184 | + CCU_PARENT_HW(pll2_d7), | ||
1185 | + CCU_PARENT_HW(pll2_d8), | ||
1186 | +}; | ||
1187 | +static CCU_DIV2_FC_MUX_GATE_DEFINE(dpu_pxclk, "dpu_pxclk", dpupx_parents, | ||
1188 | + APMU_LCD_CLK_RES_CTRL2, | ||
1189 | + APMU_LCD_CLK_RES_CTRL1, | ||
1190 | + 17, 4, BIT(30), | ||
1191 | + 21, 3, BIT(16), BIT(16), 0x0, | ||
1192 | + 0); | ||
1193 | + | ||
1194 | +static CCU_GATE_DEFINE(dpu_hclk, "dpu_hclk", CCU_PARENT_HW(pmua_aclk), | ||
1195 | + APMU_LCD_CLK_RES_CTRL1, | ||
1196 | + BIT(5), BIT(5), 0x0, | ||
1197 | + 0); | ||
1198 | + | ||
1199 | +static const struct clk_parent_data dpu_spi_parents[] = { | ||
1200 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1201 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1202 | + CCU_PARENT_HW(pll1_d10_245p76), | ||
1203 | + CCU_PARENT_HW(pll1_d11_223p4), | ||
1204 | + CCU_PARENT_HW(pll1_d13_189), | ||
1205 | + CCU_PARENT_HW(pll1_d23_106p8), | ||
1206 | + CCU_PARENT_HW(pll2_d3), | ||
1207 | + CCU_PARENT_HW(pll2_d5), | ||
1208 | +}; | ||
1209 | +static CCU_DIV_FC_MUX_GATE_DEFINE(dpu_spi_clk, "dpu_spi_clk", dpu_spi_parents, | ||
1210 | + APMU_LCD_SPI_CLK_RES_CTRL, | ||
1211 | + 8, 3, BIT(7), | ||
1212 | + 12, 3, BIT(1), BIT(1), 0x0, | ||
1213 | + 0); | ||
1214 | +static CCU_GATE_DEFINE(dpu_spi_hbus_clk, "dpu_spi_hbus_clk", CCU_PARENT_HW(pmua_aclk), | ||
1215 | + APMU_LCD_SPI_CLK_RES_CTRL, | ||
1216 | + BIT(3), BIT(3), 0x0, | ||
1217 | + 0); | ||
1218 | +static CCU_GATE_DEFINE(dpu_spi_bus_clk, "dpu_spi_bus_clk", CCU_PARENT_HW(pmua_aclk), | ||
1219 | + APMU_LCD_SPI_CLK_RES_CTRL, | ||
1220 | + BIT(5), BIT(5), 0x0, | ||
1221 | + 0); | ||
1222 | +static CCU_GATE_DEFINE(dpu_spi_aclk, "dpu_spi_aclk", CCU_PARENT_HW(pmua_aclk), | ||
1223 | + APMU_LCD_SPI_CLK_RES_CTRL, | ||
1224 | + BIT(6), BIT(6), 0x0, | ||
1225 | + 0); | ||
1226 | + | ||
1227 | +static const struct clk_parent_data v2d_parents[] = { | ||
1228 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1229 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1230 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1231 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1232 | +}; | ||
1233 | +static CCU_DIV_FC_MUX_GATE_DEFINE(v2d_clk, "v2d_clk", v2d_parents, | ||
1234 | + APMU_LCD_CLK_RES_CTRL1, | ||
1235 | + 9, 3, BIT(28), | ||
1236 | + 12, 2, BIT(8), BIT(8), 0x0, | ||
1237 | + 0); | ||
1238 | + | ||
1239 | +static const struct clk_parent_data ccic_4x_parents[] = { | ||
1240 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1241 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1242 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1243 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1244 | + CCU_PARENT_HW(pll2_d2), | ||
1245 | + CCU_PARENT_HW(pll2_d3), | ||
1246 | + CCU_PARENT_HW(pll2_d4), | ||
1247 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
1248 | +}; | ||
1249 | +static CCU_DIV_FC_MUX_GATE_DEFINE(ccic_4x_clk, "ccic_4x_clk", ccic_4x_parents, | ||
1250 | + APMU_CCIC_CLK_RES_CTRL, | ||
1251 | + 18, 3, BIT(15), | ||
1252 | + 23, 2, BIT(4), BIT(4), 0x0, | ||
1253 | + 0); | ||
1254 | + | ||
1255 | +static const struct clk_parent_data ccic1phy_parents[] = { | ||
1256 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
1257 | + CCU_PARENT_HW(pll1_d48_51p2_ap), | ||
1258 | +}; | ||
1259 | +static CCU_MUX_GATE_DEFINE(ccic1phy_clk, "ccic1phy_clk", ccic1phy_parents, | ||
1260 | + APMU_CCIC_CLK_RES_CTRL, | ||
1261 | + 7, 1, BIT(5), BIT(5), 0x0, | ||
1262 | + 0); | ||
1263 | + | ||
1264 | +static CCU_GATE_DEFINE(sdh_axi_aclk, "sdh_axi_aclk", CCU_PARENT_HW(pmua_aclk), | ||
1265 | + APMU_SDH0_CLK_RES_CTRL, | ||
1266 | + BIT(3), BIT(3), 0x0, | ||
1267 | + 0); | ||
1268 | +static const struct clk_parent_data sdh01_parents[] = { | ||
1269 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1270 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1271 | + CCU_PARENT_HW(pll2_d8), | ||
1272 | + CCU_PARENT_HW(pll2_d5), | ||
1273 | + CCU_PARENT_HW(pll1_d11_223p4), | ||
1274 | + CCU_PARENT_HW(pll1_d13_189), | ||
1275 | + CCU_PARENT_HW(pll1_d23_106p8), | ||
1276 | +}; | ||
1277 | +static CCU_DIV_FC_MUX_GATE_DEFINE(sdh0_clk, "sdh0_clk", sdh01_parents, | ||
1278 | + APMU_SDH0_CLK_RES_CTRL, | ||
1279 | + 8, 3, BIT(11), | ||
1280 | + 5, 3, BIT(4), BIT(4), 0x0, | ||
1281 | + 0); | ||
1282 | +static CCU_DIV_FC_MUX_GATE_DEFINE(sdh1_clk, "sdh1_clk", sdh01_parents, | ||
1283 | + APMU_SDH1_CLK_RES_CTRL, | ||
1284 | + 8, 3, BIT(11), | ||
1285 | + 5, 3, BIT(4), BIT(4), 0x0, | ||
1286 | + 0); | ||
1287 | +static const struct clk_parent_data sdh2_parents[] = { | ||
1288 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1289 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1290 | + CCU_PARENT_HW(pll2_d8), | ||
1291 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1292 | + CCU_PARENT_HW(pll1_d11_223p4), | ||
1293 | + CCU_PARENT_HW(pll1_d13_189), | ||
1294 | + CCU_PARENT_HW(pll1_d23_106p8), | ||
1295 | +}; | ||
1296 | +static CCU_DIV_FC_MUX_GATE_DEFINE(sdh2_clk, "sdh2_clk", sdh2_parents, | ||
1297 | + APMU_SDH2_CLK_RES_CTRL, | ||
1298 | + 8, 3, BIT(11), | ||
1299 | + 5, 3, BIT(4), BIT(4), 0x0, | ||
1300 | + 0); | ||
1301 | + | ||
1302 | +static CCU_GATE_DEFINE(usb_axi_clk, "usb_axi_clk", CCU_PARENT_HW(pmua_aclk), | ||
1303 | + APMU_USB_CLK_RES_CTRL, | ||
1304 | + BIT(1), BIT(1), 0x0, | ||
1305 | + 0); | ||
1306 | +static CCU_GATE_DEFINE(usb_p1_aclk, "usb_p1_aclk", CCU_PARENT_HW(pmua_aclk), | ||
1307 | + APMU_USB_CLK_RES_CTRL, | ||
1308 | + BIT(5), BIT(5), 0x0, | ||
1309 | + 0); | ||
1310 | +static CCU_GATE_DEFINE(usb30_clk, "usb30_clk", CCU_PARENT_HW(pmua_aclk), | ||
1311 | + APMU_USB_CLK_RES_CTRL, | ||
1312 | + BIT(8), BIT(8), 0x0, | ||
1313 | + 0); | ||
1314 | + | ||
1315 | +static const struct clk_parent_data qspi_parents[] = { | ||
1316 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1317 | + CCU_PARENT_HW(pll2_d8), | ||
1318 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1319 | + CCU_PARENT_HW(pll1_d10_245p76), | ||
1320 | + CCU_PARENT_HW(pll1_d11_223p4), | ||
1321 | + CCU_PARENT_HW(pll1_d23_106p8), | ||
1322 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1323 | + CCU_PARENT_HW(pll1_d13_189), | ||
1324 | +}; | ||
1325 | +static CCU_DIV_FC_MUX_GATE_DEFINE(qspi_clk, "qspi_clk", qspi_parents, | ||
1326 | + APMU_QSPI_CLK_RES_CTRL, | ||
1327 | + 9, 3, BIT(12), | ||
1328 | + 6, 3, BIT(4), BIT(4), 0x0, | ||
1329 | + 0); | ||
1330 | +static CCU_GATE_DEFINE(qspi_bus_clk, "qspi_bus_clk", CCU_PARENT_HW(pmua_aclk), | ||
1331 | + APMU_QSPI_CLK_RES_CTRL, | ||
1332 | + BIT(3), BIT(3), 0x0, | ||
1333 | + 0); | ||
1334 | +static CCU_GATE_DEFINE(dma_clk, "dma_clk", CCU_PARENT_HW(pmua_aclk), | ||
1335 | + APMU_DMA_CLK_RES_CTRL, | ||
1336 | + BIT(3), BIT(3), 0x0, | ||
1337 | + 0); | ||
1338 | + | ||
1339 | +static const struct clk_parent_data aes_parents[] = { | ||
1340 | + CCU_PARENT_HW(pll1_d12_204p8), | ||
1341 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
1342 | +}; | ||
1343 | +static CCU_MUX_GATE_DEFINE(aes_clk, "aes_clk", aes_parents, | ||
1344 | + APMU_AES_CLK_RES_CTRL, | ||
1345 | + 6, 1, BIT(5), BIT(5), 0x0, | ||
1346 | + 0); | ||
1347 | + | ||
1348 | +static const struct clk_parent_data vpu_parents[] = { | ||
1349 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1350 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1351 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1352 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1353 | + CCU_PARENT_HW(pll3_d6), | ||
1354 | + CCU_PARENT_HW(pll2_d3), | ||
1355 | + CCU_PARENT_HW(pll2_d4), | ||
1356 | + CCU_PARENT_HW(pll2_d5), | ||
1357 | +}; | ||
1358 | +static CCU_DIV_FC_MUX_GATE_DEFINE(vpu_clk, "vpu_clk", vpu_parents, | ||
1359 | + APMU_VPU_CLK_RES_CTRL, | ||
1360 | + 13, 3, BIT(21), | ||
1361 | + 10, 3, | ||
1362 | + BIT(3), BIT(3), 0x0, | ||
1363 | + 0); | ||
1364 | + | ||
1365 | +static const struct clk_parent_data gpu_parents[] = { | ||
1366 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1367 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1368 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1369 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1370 | + CCU_PARENT_HW(pll3_d6), | ||
1371 | + CCU_PARENT_HW(pll2_d3), | ||
1372 | + CCU_PARENT_HW(pll2_d4), | ||
1373 | + CCU_PARENT_HW(pll2_d5), | ||
1374 | +}; | ||
1375 | +static CCU_DIV_FC_MUX_GATE_DEFINE(gpu_clk, "gpu_clk", gpu_parents, | ||
1376 | + APMU_GPU_CLK_RES_CTRL, | ||
1377 | + 12, 3, BIT(15), | ||
1378 | + 18, 3, | ||
1379 | + BIT(4), BIT(4), 0x0, | ||
1380 | + 0); | ||
1381 | + | ||
1382 | +static const struct clk_parent_data emmc_parents[] = { | ||
1383 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1384 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1385 | + CCU_PARENT_HW(pll1_d52_47p26), | ||
1386 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1387 | +}; | ||
1388 | +static CCU_DIV_FC_MUX_GATE_DEFINE(emmc_clk, "emmc_clk", emmc_parents, | ||
1389 | + APMU_PMUA_EM_CLK_RES_CTRL, | ||
1390 | + 8, 3, BIT(11), | ||
1391 | + 6, 2, | ||
1392 | + BIT(4), BIT(4), 0x0, | ||
1393 | + 0); | ||
1394 | +static CCU_DIV_GATE_DEFINE(emmc_x_clk, "emmc_x_clk", CCU_PARENT_HW(pll1_d2_1228p8), | ||
1395 | + APMU_PMUA_EM_CLK_RES_CTRL, | ||
1396 | + 12, 3, BIT(15), BIT(15), 0x0, | ||
1397 | + 0); | ||
1398 | + | ||
1399 | +static const struct clk_parent_data audio_parents[] = { | ||
1400 | + CCU_PARENT_HW(pll1_aud_245p7), | ||
1401 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1402 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1403 | +}; | ||
1404 | +static CCU_DIV_FC_MUX_GATE_DEFINE(audio_clk, "audio_clk", audio_parents, | ||
1405 | + APMU_AUDIO_CLK_RES_CTRL, | ||
1406 | + 4, 3, BIT(15), | ||
1407 | + 7, 3, | ||
1408 | + BIT(12), BIT(12), 0x0, | ||
1409 | + 0); | ||
1410 | + | ||
1411 | +static const struct clk_parent_data hdmi_parents[] = { | ||
1412 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1413 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1414 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1415 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1416 | +}; | ||
1417 | +static CCU_DIV_FC_MUX_GATE_DEFINE(hdmi_mclk, "hdmi_mclk", hdmi_parents, | ||
1418 | + APMU_HDMI_CLK_RES_CTRL, | ||
1419 | + 1, 4, BIT(29), | ||
1420 | + 5, 3, | ||
1421 | + BIT(0), BIT(0), 0x0, | ||
1422 | + 0); | ||
1423 | + | ||
1424 | +static CCU_GATE_DEFINE(pcie0_clk, "pcie0_clk", CCU_PARENT_HW(pmua_aclk), | ||
1425 | + APMU_PCIE_CLK_RES_CTRL_0, | ||
1426 | + 0x7, 0x7, 0x0, | ||
1427 | + 0); | ||
1428 | +static CCU_GATE_DEFINE(pcie1_clk, "pcie1_clk", CCU_PARENT_HW(pmua_aclk), | ||
1429 | + APMU_PCIE_CLK_RES_CTRL_1, | ||
1430 | + 0x7, 0x7, 0x0, | ||
1431 | + 0); | ||
1432 | +static CCU_GATE_DEFINE(pcie2_clk, "pcie2_clk", CCU_PARENT_HW(pmua_aclk), | ||
1433 | + APMU_PCIE_CLK_RES_CTRL_2, | ||
1434 | + 0x7, 0x7, 0x0, | ||
1435 | + 0); | ||
1436 | + | ||
1437 | +static CCU_GATE_DEFINE(emac0_bus_clk, "emac0_bus_clk", CCU_PARENT_HW(pmua_aclk), | ||
1438 | + APMU_EMAC0_CLK_RES_CTRL, | ||
1439 | + BIT(0), BIT(0), 0x0, | ||
1440 | + 0); | ||
1441 | +static CCU_GATE_DEFINE(emac0_ptp_clk, "emac0_ptp_clk", CCU_PARENT_HW(pll2_d6), | ||
1442 | + APMU_EMAC0_CLK_RES_CTRL, | ||
1443 | + BIT(15), BIT(15), 0x0, | ||
1444 | + 0); | ||
1445 | +static CCU_GATE_DEFINE(emac1_bus_clk, "emac1_bus_clk", CCU_PARENT_HW(pmua_aclk), | ||
1446 | + APMU_EMAC1_CLK_RES_CTRL, | ||
1447 | + BIT(0), BIT(0), 0x0, | ||
1448 | + 0); | ||
1449 | +static CCU_GATE_DEFINE(emac1_ptp_clk, "emac1_ptp_clk", CCU_PARENT_HW(pll2_d6), | ||
1450 | + APMU_EMAC1_CLK_RES_CTRL, | ||
1451 | + BIT(15), BIT(15), 0x0, | ||
1452 | + 0); | ||
1453 | + | ||
1454 | +static CCU_GATE_DEFINE(emmc_bus_clk, "emmc_bus_clk", CCU_PARENT_HW(pmua_aclk), | ||
1455 | + APMU_PMUA_EM_CLK_RES_CTRL, | ||
1456 | + BIT(3), BIT(3), 0, | ||
1457 | + 0); | ||
1458 | +/* APMU clocks end */ | ||
1459 | + | ||
1460 | +static struct clk_hw_onecell_data k1_ccu_apbs_clks = { | ||
1461 | + .hws = { | ||
1462 | + [CLK_PLL1] = &pll1.common.hw, | ||
1463 | + [CLK_PLL2] = &pll2.common.hw, | ||
1464 | + [CLK_PLL3] = &pll3.common.hw, | ||
1465 | + [CLK_PLL1_D2] = &pll1_d2.common.hw, | ||
1466 | + [CLK_PLL1_D3] = &pll1_d3.common.hw, | ||
1467 | + [CLK_PLL1_D4] = &pll1_d4.common.hw, | ||
1468 | + [CLK_PLL1_D5] = &pll1_d5.common.hw, | ||
1469 | + [CLK_PLL1_D6] = &pll1_d6.common.hw, | ||
1470 | + [CLK_PLL1_D7] = &pll1_d7.common.hw, | ||
1471 | + [CLK_PLL1_D8] = &pll1_d8.common.hw, | ||
1472 | + [CLK_PLL1_D11] = &pll1_d11_223p4.common.hw, | ||
1473 | + [CLK_PLL1_D13] = &pll1_d13_189.common.hw, | ||
1474 | + [CLK_PLL1_D23] = &pll1_d23_106p8.common.hw, | ||
1475 | + [CLK_PLL1_D64] = &pll1_d64_38p4.common.hw, | ||
1476 | + [CLK_PLL1_D10_AUD] = &pll1_aud_245p7.common.hw, | ||
1477 | + [CLK_PLL1_D100_AUD] = &pll1_aud_24p5.common.hw, | ||
1478 | + [CLK_PLL2_D1] = &pll2_d1.common.hw, | ||
1479 | + [CLK_PLL2_D2] = &pll2_d2.common.hw, | ||
1480 | + [CLK_PLL2_D3] = &pll2_d3.common.hw, | ||
1481 | + [CLK_PLL2_D4] = &pll2_d4.common.hw, | ||
1482 | + [CLK_PLL2_D5] = &pll2_d5.common.hw, | ||
1483 | + [CLK_PLL2_D6] = &pll2_d6.common.hw, | ||
1484 | + [CLK_PLL2_D7] = &pll2_d7.common.hw, | ||
1485 | + [CLK_PLL2_D8] = &pll2_d8.common.hw, | ||
1486 | + [CLK_PLL3_D1] = &pll3_d1.common.hw, | ||
1487 | + [CLK_PLL3_D2] = &pll3_d2.common.hw, | ||
1488 | + [CLK_PLL3_D3] = &pll3_d3.common.hw, | ||
1489 | + [CLK_PLL3_D4] = &pll3_d4.common.hw, | ||
1490 | + [CLK_PLL3_D5] = &pll3_d5.common.hw, | ||
1491 | + [CLK_PLL3_D6] = &pll3_d6.common.hw, | ||
1492 | + [CLK_PLL3_D7] = &pll3_d7.common.hw, | ||
1493 | + [CLK_PLL3_D8] = &pll3_d8.common.hw, | ||
1494 | + [CLK_PLL3_80] = &pll3_80.common.hw, | ||
1495 | + [CLK_PLL3_40] = &pll3_40.common.hw, | ||
1496 | + [CLK_PLL3_20] = &pll3_20.common.hw, | ||
1497 | + | ||
1498 | + }, | ||
1499 | + .num = CLK_APBS_NUM, | ||
1500 | +}; | ||
1501 | + | ||
1502 | +static struct clk_hw_onecell_data k1_ccu_mpmu_clks = { | ||
1503 | + .hws = { | ||
1504 | + [CLK_PLL1_307P2] = &pll1_d8_307p2.common.hw, | ||
1505 | + [CLK_PLL1_76P8] = &pll1_d32_76p8.common.hw, | ||
1506 | + [CLK_PLL1_61P44] = &pll1_d40_61p44.common.hw, | ||
1507 | + [CLK_PLL1_153P6] = &pll1_d16_153p6.common.hw, | ||
1508 | + [CLK_PLL1_102P4] = &pll1_d24_102p4.common.hw, | ||
1509 | + [CLK_PLL1_51P2] = &pll1_d48_51p2.common.hw, | ||
1510 | + [CLK_PLL1_51P2_AP] = &pll1_d48_51p2_ap.common.hw, | ||
1511 | + [CLK_PLL1_57P6] = &pll1_m3d128_57p6.common.hw, | ||
1512 | + [CLK_PLL1_25P6] = &pll1_d96_25p6.common.hw, | ||
1513 | + [CLK_PLL1_12P8] = &pll1_d192_12p8.common.hw, | ||
1514 | + [CLK_PLL1_12P8_WDT] = &pll1_d192_12p8_wdt.common.hw, | ||
1515 | + [CLK_PLL1_6P4] = &pll1_d384_6p4.common.hw, | ||
1516 | + [CLK_PLL1_3P2] = &pll1_d768_3p2.common.hw, | ||
1517 | + [CLK_PLL1_1P6] = &pll1_d1536_1p6.common.hw, | ||
1518 | + [CLK_PLL1_0P8] = &pll1_d3072_0p8.common.hw, | ||
1519 | + [CLK_PLL1_351] = &pll1_d7_351p08.common.hw, | ||
1520 | + [CLK_PLL1_409P6] = &pll1_d6_409p6.common.hw, | ||
1521 | + [CLK_PLL1_204P8] = &pll1_d12_204p8.common.hw, | ||
1522 | + [CLK_PLL1_491] = &pll1_d5_491p52.common.hw, | ||
1523 | + [CLK_PLL1_245P76] = &pll1_d10_245p76.common.hw, | ||
1524 | + [CLK_PLL1_614] = &pll1_d4_614p4.common.hw, | ||
1525 | + [CLK_PLL1_47P26] = &pll1_d52_47p26.common.hw, | ||
1526 | + [CLK_PLL1_31P5] = &pll1_d78_31p5.common.hw, | ||
1527 | + [CLK_PLL1_819] = &pll1_d3_819p2.common.hw, | ||
1528 | + [CLK_PLL1_1228] = &pll1_d2_1228p8.common.hw, | ||
1529 | + [CLK_SLOW_UART] = &slow_uart.common.hw, | ||
1530 | + [CLK_SLOW_UART1] = &slow_uart1_14p74.common.hw, | ||
1531 | + [CLK_SLOW_UART2] = &slow_uart2_48.common.hw, | ||
1532 | + [CLK_WDT] = &wdt_clk.common.hw, | ||
1533 | + [CLK_RIPC] = &ripc_clk.common.hw, | ||
1534 | + [CLK_I2S_SYSCLK] = &i2s_sysclk.common.hw, | ||
1535 | + [CLK_I2S_BCLK] = &i2s_bclk.common.hw, | ||
1536 | + [CLK_APB] = &apb_clk.common.hw, | ||
1537 | + [CLK_WDT_BUS] = &wdt_bus_clk.common.hw, | ||
1538 | + }, | ||
1539 | + .num = CLK_MPMU_NUM, | ||
1540 | +}; | ||
1541 | + | ||
1542 | +static struct clk_hw_onecell_data k1_ccu_apbc_clks = { | ||
1543 | + .hws = { | ||
1544 | + [CLK_UART0] = &uart0_clk.common.hw, | 102 | + [CLK_UART0] = &uart0_clk.common.hw, |
1545 | + [CLK_UART2] = &uart2_clk.common.hw, | 103 | + [CLK_UART2] = &uart2_clk.common.hw, |
1546 | + [CLK_UART3] = &uart3_clk.common.hw, | 104 | + [CLK_UART3] = &uart3_clk.common.hw, |
1547 | + [CLK_UART4] = &uart4_clk.common.hw, | 105 | + [CLK_UART4] = &uart4_clk.common.hw, |
1548 | + [CLK_UART5] = &uart5_clk.common.hw, | 106 | + [CLK_UART5] = &uart5_clk.common.hw, |
... | ... | ||
1639 | + [CLK_ONEWIRE_BUS] = &onewire_bus_clk.common.hw, | 197 | + [CLK_ONEWIRE_BUS] = &onewire_bus_clk.common.hw, |
1640 | + [CLK_SSPA0_BUS] = &sspa0_bus_clk.common.hw, | 198 | + [CLK_SSPA0_BUS] = &sspa0_bus_clk.common.hw, |
1641 | + [CLK_SSPA1_BUS] = &sspa1_bus_clk.common.hw, | 199 | + [CLK_SSPA1_BUS] = &sspa1_bus_clk.common.hw, |
1642 | + [CLK_TSEN_BUS] = &tsen_bus_clk.common.hw, | 200 | + [CLK_TSEN_BUS] = &tsen_bus_clk.common.hw, |
1643 | + [CLK_IPC_AP2AUD_BUS] = &ipc_ap2aud_bus_clk.common.hw, | 201 | + [CLK_IPC_AP2AUD_BUS] = &ipc_ap2aud_bus_clk.common.hw, |
1644 | + }, | 202 | diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c |
1645 | + .num = CLK_APBC_NUM, | 203 | new file mode 100644 |
1646 | +}; | 204 | index XXXXXXX..XXXXXXX |
1647 | + | 205 | --- /dev/null |
1648 | +static struct clk_hw_onecell_data k1_ccu_apmu_clks = { | 206 | +++ b/drivers/clk/spacemit/ccu-k1.c |
1649 | + .hws = { | 207 | @@ -XXX,XX +XXX,XX @@ |
1650 | + [CLK_CCI550] = &cci550_clk.common.hw, | 208 | +// SPDX-License-Identifier: GPL-2.0-only |
1651 | + [CLK_CPU_C0_HI] = &cpu_c0_hi_clk.common.hw, | 209 | +/* |
1652 | + [CLK_CPU_C0_CORE] = &cpu_c0_core_clk.common.hw, | 210 | + * Copyright (c) 2024 SpacemiT Technology Co. Ltd |
1653 | + [CLK_CPU_C0_ACE] = &cpu_c0_ace_clk.common.hw, | 211 | + * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org> |
1654 | + [CLK_CPU_C0_TCM] = &cpu_c0_tcm_clk.common.hw, | 212 | + */ |
1655 | + [CLK_CPU_C1_HI] = &cpu_c1_hi_clk.common.hw, | 213 | + |
1656 | + [CLK_CPU_C1_CORE] = &cpu_c1_core_clk.common.hw, | 214 | +#include <linux/array_size.h> |
1657 | + [CLK_CPU_C1_ACE] = &cpu_c1_ace_clk.common.hw, | 215 | +#include <linux/clk-provider.h> |
1658 | + [CLK_CCIC_4X] = &ccic_4x_clk.common.hw, | 216 | +#include <linux/delay.h> |
1659 | + [CLK_CCIC1PHY] = &ccic1phy_clk.common.hw, | 217 | +#include <linux/mfd/syscon.h> |
1660 | + [CLK_SDH_AXI] = &sdh_axi_aclk.common.hw, | 218 | +#include <linux/minmax.h> |
1661 | + [CLK_SDH0] = &sdh0_clk.common.hw, | 219 | +#include <linux/module.h> |
1662 | + [CLK_SDH1] = &sdh1_clk.common.hw, | 220 | +#include <linux/platform_device.h> |
1663 | + [CLK_SDH2] = &sdh2_clk.common.hw, | 221 | + |
1664 | + [CLK_USB_P1] = &usb_p1_aclk.common.hw, | 222 | +#include "ccu_common.h" |
1665 | + [CLK_USB_AXI] = &usb_axi_clk.common.hw, | 223 | +#include "ccu_pll.h" |
1666 | + [CLK_USB30] = &usb30_clk.common.hw, | 224 | +#include "ccu_mix.h" |
1667 | + [CLK_QSPI] = &qspi_clk.common.hw, | 225 | +#include "ccu_ddn.h" |
1668 | + [CLK_QSPI_BUS] = &qspi_bus_clk.common.hw, | 226 | + |
1669 | + [CLK_DMA] = &dma_clk.common.hw, | 227 | +#include <dt-bindings/clock/spacemit,k1-syscon.h> |
1670 | + [CLK_AES] = &aes_clk.common.hw, | 228 | + |
1671 | + [CLK_VPU] = &vpu_clk.common.hw, | 229 | +/* APBS register offset */ |
1672 | + [CLK_GPU] = &gpu_clk.common.hw, | 230 | +#define APBS_PLL1_SWCR1 0x100 |
1673 | + [CLK_EMMC] = &emmc_clk.common.hw, | 231 | +#define APBS_PLL1_SWCR2 0x104 |
1674 | + [CLK_EMMC_X] = &emmc_x_clk.common.hw, | 232 | +#define APBS_PLL1_SWCR3 0x108 |
1675 | + [CLK_AUDIO] = &audio_clk.common.hw, | 233 | +#define APBS_PLL2_SWCR1 0x118 |
1676 | + [CLK_HDMI] = &hdmi_mclk.common.hw, | 234 | +#define APBS_PLL2_SWCR2 0x11c |
1677 | + [CLK_PMUA_ACLK] = &pmua_aclk.common.hw, | 235 | +#define APBS_PLL2_SWCR3 0x120 |
1678 | + [CLK_PCIE0] = &pcie0_clk.common.hw, | 236 | +#define APBS_PLL3_SWCR1 0x124 |
1679 | + [CLK_PCIE1] = &pcie1_clk.common.hw, | 237 | +#define APBS_PLL3_SWCR2 0x128 |
1680 | + [CLK_PCIE2] = &pcie2_clk.common.hw, | 238 | +#define APBS_PLL3_SWCR3 0x12c |
1681 | + [CLK_EMAC0_BUS] = &emac0_bus_clk.common.hw, | 239 | + |
1682 | + [CLK_EMAC0_PTP] = &emac0_ptp_clk.common.hw, | 240 | +/* MPMU register offset */ |
1683 | + [CLK_EMAC1_BUS] = &emac1_bus_clk.common.hw, | 241 | +#define MPMU_POSR 0x0010 |
1684 | + [CLK_EMAC1_PTP] = &emac1_ptp_clk.common.hw, | 242 | +#define POSR_PLL1_LOCK BIT(27) |
1685 | + [CLK_JPG] = &jpg_clk.common.hw, | 243 | +#define POSR_PLL2_LOCK BIT(28) |
1686 | + [CLK_CCIC2PHY] = &ccic2phy_clk.common.hw, | 244 | +#define POSR_PLL3_LOCK BIT(29) |
1687 | + [CLK_CCIC3PHY] = &ccic3phy_clk.common.hw, | 245 | +#define MPMU_SUCCR 0x0014 |
1688 | + [CLK_CSI] = &csi_clk.common.hw, | 246 | +#define MPMU_ISCCR 0x0044 |
1689 | + [CLK_CAMM0] = &camm0_clk.common.hw, | 247 | +#define MPMU_WDTPCR 0x0200 |
1690 | + [CLK_CAMM1] = &camm1_clk.common.hw, | 248 | +#define MPMU_RIPCCR 0x0210 |
1691 | + [CLK_CAMM2] = &camm2_clk.common.hw, | 249 | +#define MPMU_ACGR 0x1024 |
1692 | + [CLK_ISP_CPP] = &isp_cpp_clk.common.hw, | 250 | +#define MPMU_APBCSCR 0x1050 |
1693 | + [CLK_ISP_BUS] = &isp_bus_clk.common.hw, | 251 | +#define MPMU_SUCCR_1 0x10b0 |
1694 | + [CLK_ISP] = &isp_clk.common.hw, | 252 | + |
1695 | + [CLK_DPU_MCLK] = &dpu_mclk.common.hw, | 253 | +/* APBC register offset */ |
1696 | + [CLK_DPU_ESC] = &dpu_esc_clk.common.hw, | 254 | +#define APBC_UART1_CLK_RST 0x00 |
1697 | + [CLK_DPU_BIT] = &dpu_bit_clk.common.hw, | 255 | +#define APBC_UART2_CLK_RST 0x04 |
1698 | + [CLK_DPU_PXCLK] = &dpu_pxclk.common.hw, | 256 | +#define APBC_GPIO_CLK_RST 0x08 |
1699 | + [CLK_DPU_HCLK] = &dpu_hclk.common.hw, | 257 | +#define APBC_PWM0_CLK_RST 0x0c |
1700 | + [CLK_DPU_SPI] = &dpu_spi_clk.common.hw, | 258 | +#define APBC_PWM1_CLK_RST 0x10 |
1701 | + [CLK_DPU_SPI_HBUS] = &dpu_spi_hbus_clk.common.hw, | 259 | +#define APBC_PWM2_CLK_RST 0x14 |
1702 | + [CLK_DPU_SPIBUS] = &dpu_spi_bus_clk.common.hw, | 260 | +#define APBC_PWM3_CLK_RST 0x18 |
1703 | + [CLK_DPU_SPI_ACLK] = &dpu_spi_aclk.common.hw, | 261 | +#define APBC_TWSI8_CLK_RST 0x20 |
1704 | + [CLK_V2D] = &v2d_clk.common.hw, | 262 | +#define APBC_UART3_CLK_RST 0x24 |
1705 | + [CLK_EMMC_BUS] = &emmc_bus_clk.common.hw, | 263 | +#define APBC_RTC_CLK_RST 0x28 |
1706 | + }, | 264 | +#define APBC_TWSI0_CLK_RST 0x2c |
1707 | + .num = CLK_APMU_NUM | 265 | +#define APBC_TWSI1_CLK_RST 0x30 |
1708 | +}; | 266 | +#define APBC_TIMERS1_CLK_RST 0x34 |
267 | +#define APBC_TWSI2_CLK_RST 0x38 | ||
268 | +#define APBC_AIB_CLK_RST 0x3c | ||
269 | +#define APBC_TWSI4_CLK_RST 0x40 | ||
270 | +#define APBC_TIMERS2_CLK_RST 0x44 | ||
271 | +#define APBC_ONEWIRE_CLK_RST 0x48 | ||
272 | +#define APBC_TWSI5_CLK_RST 0x4c | ||
273 | +#define APBC_DRO_CLK_RST 0x58 | ||
274 | +#define APBC_IR_CLK_RST 0x5c | ||
275 | +#define APBC_TWSI6_CLK_RST 0x60 | ||
276 | +#define APBC_COUNTER_CLK_SEL 0x64 | ||
277 | +#define APBC_TWSI7_CLK_RST 0x68 | ||
278 | +#define APBC_TSEN_CLK_RST 0x6c | ||
279 | +#define APBC_UART4_CLK_RST 0x70 | ||
280 | +#define APBC_UART5_CLK_RST 0x74 | ||
281 | +#define APBC_UART6_CLK_RST 0x78 | ||
282 | +#define APBC_SSP3_CLK_RST 0x7c | ||
283 | +#define APBC_SSPA0_CLK_RST 0x80 | ||
284 | +#define APBC_SSPA1_CLK_RST 0x84 | ||
285 | +#define APBC_IPC_AP2AUD_CLK_RST 0x90 | ||
286 | +#define APBC_UART7_CLK_RST 0x94 | ||
287 | +#define APBC_UART8_CLK_RST 0x98 | ||
288 | +#define APBC_UART9_CLK_RST 0x9c | ||
289 | +#define APBC_CAN0_CLK_RST 0xa0 | ||
290 | +#define APBC_PWM4_CLK_RST 0xa8 | ||
291 | +#define APBC_PWM5_CLK_RST 0xac | ||
292 | +#define APBC_PWM6_CLK_RST 0xb0 | ||
293 | +#define APBC_PWM7_CLK_RST 0xb4 | ||
294 | +#define APBC_PWM8_CLK_RST 0xb8 | ||
295 | +#define APBC_PWM9_CLK_RST 0xbc | ||
296 | +#define APBC_PWM10_CLK_RST 0xc0 | ||
297 | +#define APBC_PWM11_CLK_RST 0xc4 | ||
298 | +#define APBC_PWM12_CLK_RST 0xc8 | ||
299 | +#define APBC_PWM13_CLK_RST 0xcc | ||
300 | +#define APBC_PWM14_CLK_RST 0xd0 | ||
301 | +#define APBC_PWM15_CLK_RST 0xd4 | ||
302 | +#define APBC_PWM16_CLK_RST 0xd8 | ||
303 | +#define APBC_PWM17_CLK_RST 0xdc | ||
304 | +#define APBC_PWM18_CLK_RST 0xe0 | ||
305 | +#define APBC_PWM19_CLK_RST 0xe4 | ||
306 | + | ||
307 | +/* APMU register offset */ | ||
308 | +#define APMU_JPG_CLK_RES_CTRL 0x020 | ||
309 | +#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x024 | ||
310 | +#define APMU_ISP_CLK_RES_CTRL 0x038 | ||
311 | +#define APMU_LCD_CLK_RES_CTRL1 0x044 | ||
312 | +#define APMU_LCD_SPI_CLK_RES_CTRL 0x048 | ||
313 | +#define APMU_LCD_CLK_RES_CTRL2 0x04c | ||
314 | +#define APMU_CCIC_CLK_RES_CTRL 0x050 | ||
315 | +#define APMU_SDH0_CLK_RES_CTRL 0x054 | ||
316 | +#define APMU_SDH1_CLK_RES_CTRL 0x058 | ||
317 | +#define APMU_USB_CLK_RES_CTRL 0x05c | ||
318 | +#define APMU_QSPI_CLK_RES_CTRL 0x060 | ||
319 | +#define APMU_DMA_CLK_RES_CTRL 0x064 | ||
320 | +#define APMU_AES_CLK_RES_CTRL 0x068 | ||
321 | +#define APMU_VPU_CLK_RES_CTRL 0x0a4 | ||
322 | +#define APMU_GPU_CLK_RES_CTRL 0x0cc | ||
323 | +#define APMU_SDH2_CLK_RES_CTRL 0x0e0 | ||
324 | +#define APMU_PMUA_MC_CTRL 0x0e8 | ||
325 | +#define APMU_PMU_CC2_AP 0x100 | ||
326 | +#define APMU_PMUA_EM_CLK_RES_CTRL 0x104 | ||
327 | +#define APMU_AUDIO_CLK_RES_CTRL 0x14c | ||
328 | +#define APMU_HDMI_CLK_RES_CTRL 0x1b8 | ||
329 | +#define APMU_CCI550_CLK_CTRL 0x300 | ||
330 | +#define APMU_ACLK_CLK_CTRL 0x388 | ||
331 | +#define APMU_CPU_C0_CLK_CTRL 0x38C | ||
332 | +#define APMU_CPU_C1_CLK_CTRL 0x390 | ||
333 | +#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc | ||
334 | +#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4 | ||
335 | +#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc | ||
336 | +#define APMU_EMAC0_CLK_RES_CTRL 0x3e4 | ||
337 | +#define APMU_EMAC1_CLK_RES_CTRL 0x3ec | ||
338 | + | ||
339 | +/* APBS clocks start, APBS region contains and only contains all PLL clocks */ | ||
340 | + | ||
341 | +/* Frequency of pll{1,2} must not be updated at runtime */ | ||
342 | +static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = { | ||
343 | + CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd), | ||
344 | +}; | ||
345 | + | ||
346 | +static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = { | ||
347 | + CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd), | ||
348 | + CCU_PLL_RATE(2800000000UL, 0x0050dd66, 0x3a155555), | ||
349 | + CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000), | ||
350 | + CCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab), | ||
351 | +}; | ||
352 | + | ||
353 | +static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = { | ||
354 | + CCU_PLL_RATE(1600000000UL, 0x0050cd61, 0x43eaaaab), | ||
355 | + CCU_PLL_RATE(1800000000UL, 0x0050cd61, 0x4b000000), | ||
356 | + CCU_PLL_RATE(2000000000UL, 0x0050dd62, 0x2aeaaaab), | ||
357 | + CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd), | ||
358 | + CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000), | ||
359 | + CCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab), | ||
360 | +}; | ||
361 | + | ||
362 | +CCU_PLL_DEFINE(pll1, pll1_rate_tbl, APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, MPMU_POSR, | ||
363 | + POSR_PLL1_LOCK, CLK_SET_RATE_GATE); | ||
364 | +CCU_PLL_DEFINE(pll2, pll2_rate_tbl, APBS_PLL2_SWCR1, APBS_PLL2_SWCR3, MPMU_POSR, | ||
365 | + POSR_PLL2_LOCK, CLK_SET_RATE_GATE); | ||
366 | +CCU_PLL_DEFINE(pll3, pll3_rate_tbl, APBS_PLL3_SWCR1, APBS_PLL3_SWCR3, MPMU_POSR, | ||
367 | + POSR_PLL3_LOCK, CLK_SET_RATE_GATE); | ||
368 | + | ||
369 | +CCU_FACTOR_GATE_DEFINE(pll1_d2, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(1), 2, | ||
370 | + 1); | ||
371 | +CCU_FACTOR_GATE_DEFINE(pll1_d3, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(2), 3, | ||
372 | + 1); | ||
373 | +CCU_FACTOR_GATE_DEFINE(pll1_d4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(3), 4, | ||
374 | + 1); | ||
375 | +CCU_FACTOR_GATE_DEFINE(pll1_d5, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(4), 5, | ||
376 | + 1); | ||
377 | +CCU_FACTOR_GATE_DEFINE(pll1_d6, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(5), 6, | ||
378 | + 1); | ||
379 | +CCU_FACTOR_GATE_DEFINE(pll1_d7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(6), 7, | ||
380 | + 1); | ||
381 | +CCU_FACTOR_GATE_DEFINE(pll1_d8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(7), 8, | ||
382 | + 1); | ||
383 | +CCU_FACTOR_GATE_DEFINE(pll1_d11_223p4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, | ||
384 | + BIT(15), 11, 1); | ||
385 | +CCU_FACTOR_GATE_DEFINE(pll1_d13_189, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, | ||
386 | + BIT(16), 13, 1); | ||
387 | +CCU_FACTOR_GATE_DEFINE(pll1_d23_106p8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, | ||
388 | + BIT(20), 23, 1); | ||
389 | +CCU_FACTOR_GATE_DEFINE(pll1_d64_38p4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, | ||
390 | + BIT(0), 64, 1); | ||
391 | +CCU_FACTOR_GATE_DEFINE(pll1_aud_245p7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, | ||
392 | + BIT(10), 10, 1); | ||
393 | +CCU_FACTOR_GATE_DEFINE(pll1_aud_24p5, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, | ||
394 | + BIT(11), 100, 1); | ||
395 | + | ||
396 | +CCU_FACTOR_GATE_DEFINE(pll2_d1, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(0), 1, | ||
397 | + 1); | ||
398 | +CCU_FACTOR_GATE_DEFINE(pll2_d2, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(1), 2, | ||
399 | + 1); | ||
400 | +CCU_FACTOR_GATE_DEFINE(pll2_d3, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(2), 3, | ||
401 | + 1); | ||
402 | +CCU_FACTOR_GATE_DEFINE(pll2_d4, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(3), 4, | ||
403 | + 1); | ||
404 | +CCU_FACTOR_GATE_DEFINE(pll2_d5, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(4), 5, | ||
405 | + 1); | ||
406 | +CCU_FACTOR_GATE_DEFINE(pll2_d6, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(5), 6, | ||
407 | + 1); | ||
408 | +CCU_FACTOR_GATE_DEFINE(pll2_d7, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(6), 7, | ||
409 | + 1); | ||
410 | +CCU_FACTOR_GATE_DEFINE(pll2_d8, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(7), 8, | ||
411 | + 1); | ||
412 | + | ||
413 | +CCU_FACTOR_GATE_DEFINE(pll3_d1, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(0), 1, | ||
414 | + 1); | ||
415 | +CCU_FACTOR_GATE_DEFINE(pll3_d2, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(1), 2, | ||
416 | + 1); | ||
417 | +CCU_FACTOR_GATE_DEFINE(pll3_d3, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(2), 3, | ||
418 | + 1); | ||
419 | +CCU_FACTOR_GATE_DEFINE(pll3_d4, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(3), 4, | ||
420 | + 1); | ||
421 | +CCU_FACTOR_GATE_DEFINE(pll3_d5, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(4), 5, | ||
422 | + 1); | ||
423 | +CCU_FACTOR_GATE_DEFINE(pll3_d6, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(5), 6, | ||
424 | + 1); | ||
425 | +CCU_FACTOR_GATE_DEFINE(pll3_d7, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(6), 7, | ||
426 | + 1); | ||
427 | +CCU_FACTOR_GATE_DEFINE(pll3_d8, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(7), 8, | ||
428 | + 1); | ||
429 | + | ||
430 | +CCU_FACTOR_DEFINE(pll3_20, CCU_PARENT_HW(pll3_d8), 20, 1); | ||
431 | +CCU_FACTOR_DEFINE(pll3_40, CCU_PARENT_HW(pll3_d8), 10, 1); | ||
432 | +CCU_FACTOR_DEFINE(pll3_80, CCU_PARENT_HW(pll3_d8), 5, 1); | ||
433 | + | ||
434 | +/* APBS clocks end */ | ||
435 | + | ||
436 | +/* MPMU clocks start */ | ||
437 | +CCU_GATE_DEFINE(pll1_d8_307p2, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(13), 0); | ||
438 | + | ||
439 | +CCU_FACTOR_DEFINE(pll1_d32_76p8, CCU_PARENT_HW(pll1_d8_307p2), 4, 1); | ||
440 | + | ||
441 | +CCU_FACTOR_DEFINE(pll1_d40_61p44, CCU_PARENT_HW(pll1_d8_307p2), 5, 1); | ||
442 | + | ||
443 | +CCU_FACTOR_DEFINE(pll1_d16_153p6, CCU_PARENT_HW(pll1_d8), 2, 1); | ||
444 | +CCU_FACTOR_GATE_DEFINE(pll1_d24_102p4, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, | ||
445 | + BIT(12), 3, 1); | ||
446 | +CCU_FACTOR_GATE_DEFINE(pll1_d48_51p2, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(7), | ||
447 | + 6, 1); | ||
448 | +CCU_FACTOR_GATE_DEFINE(pll1_d48_51p2_ap, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, | ||
449 | + BIT(11), 6, 1); | ||
450 | +CCU_FACTOR_GATE_DEFINE(pll1_m3d128_57p6, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, | ||
451 | + BIT(8), 16, 3); | ||
452 | +CCU_FACTOR_GATE_DEFINE(pll1_d96_25p6, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(4), | ||
453 | + 12, 1); | ||
454 | +CCU_FACTOR_GATE_DEFINE(pll1_d192_12p8, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, | ||
455 | + BIT(3), 24, 1); | ||
456 | +CCU_FACTOR_GATE_DEFINE(pll1_d192_12p8_wdt, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, | ||
457 | + BIT(19), 24, 1); | ||
458 | +CCU_FACTOR_GATE_DEFINE(pll1_d384_6p4, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, | ||
459 | + BIT(2), 48, 1); | ||
460 | + | ||
461 | +CCU_FACTOR_DEFINE(pll1_d768_3p2, CCU_PARENT_HW(pll1_d384_6p4), 2, 1); | ||
462 | +CCU_FACTOR_DEFINE(pll1_d1536_1p6, CCU_PARENT_HW(pll1_d384_6p4), 4, 1); | ||
463 | +CCU_FACTOR_DEFINE(pll1_d3072_0p8, CCU_PARENT_HW(pll1_d384_6p4), 8, 1); | ||
464 | + | ||
465 | +CCU_GATE_DEFINE(pll1_d6_409p6, CCU_PARENT_HW(pll1_d6), MPMU_ACGR, BIT(0), 0); | ||
466 | +CCU_FACTOR_GATE_DEFINE(pll1_d12_204p8, CCU_PARENT_HW(pll1_d6), MPMU_ACGR, | ||
467 | + BIT(5), 2, 1); | ||
468 | + | ||
469 | +CCU_GATE_DEFINE(pll1_d5_491p52, CCU_PARENT_HW(pll1_d5), MPMU_ACGR, BIT(21), 0); | ||
470 | +CCU_FACTOR_GATE_DEFINE(pll1_d10_245p76, CCU_PARENT_HW(pll1_d5), MPMU_ACGR, | ||
471 | + BIT(18), 2, 1); | ||
472 | + | ||
473 | +CCU_GATE_DEFINE(pll1_d4_614p4, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, | ||
474 | + BIT(15), 0); | ||
475 | +CCU_FACTOR_GATE_DEFINE(pll1_d52_47p26, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, | ||
476 | + BIT(10), 13, 1); | ||
477 | +CCU_FACTOR_GATE_DEFINE(pll1_d78_31p5, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, | ||
478 | + BIT(6), 39, 2); | ||
479 | + | ||
480 | +CCU_GATE_DEFINE(pll1_d3_819p2, CCU_PARENT_HW(pll1_d3), MPMU_ACGR, BIT(14), 0); | ||
481 | + | ||
482 | +CCU_GATE_DEFINE(pll1_d2_1228p8, CCU_PARENT_HW(pll1_d2), MPMU_ACGR, BIT(16), 0); | ||
483 | + | ||
484 | +CCU_GATE_DEFINE(slow_uart, CCU_PARENT_NAME(osc), MPMU_ACGR, BIT(1), | ||
485 | + CLK_IGNORE_UNUSED); | ||
486 | +CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, MPMU_SUCCR, GENMASK(28, 16), | ||
487 | + GENMASK(12, 0), 0); | ||
488 | +CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, MPMU_SUCCR_1, GENMASK(28, 16), | ||
489 | + GENMASK(12, 0), 0); | ||
490 | + | ||
491 | +CCU_GATE_DEFINE(wdt_clk, CCU_PARENT_HW(pll1_d96_25p6), MPMU_WDTPCR, BIT(1), 0); | ||
492 | + | ||
493 | +CCU_FACTOR_GATE_DEFINE(i2s_sysclk, CCU_PARENT_HW(pll1_d16_153p6), MPMU_ISCCR, | ||
494 | + BIT(31), 50, 1); | ||
495 | +CCU_FACTOR_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s_sysclk), MPMU_ISCCR, BIT(29), | ||
496 | + 1, 1); | ||
497 | + | ||
498 | +static const struct clk_parent_data apb_parents[] = { | ||
499 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
500 | + CCU_PARENT_HW(pll1_d48_51p2), | ||
501 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
502 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
503 | +}; | ||
504 | +CCU_MUX_DEFINE(apb_clk, apb_parents, MPMU_APBCSCR, 0, 2, 0); | ||
505 | + | ||
506 | +CCU_GATE_DEFINE(wdt_bus_clk, CCU_PARENT_HW(apb_clk), MPMU_WDTPCR, BIT(0), 0); | ||
507 | + | ||
508 | +CCU_GATE_DEFINE(ripc_clk, CCU_PARENT_HW(apb_clk), MPMU_RIPCCR, 0x1, 0); | ||
509 | +/* MPMU clocks end */ | ||
510 | + | ||
511 | +/* APBC clocks start */ | ||
512 | +static const struct clk_parent_data uart_clk_parents[] = { | ||
513 | + CCU_PARENT_HW(pll1_m3d128_57p6), | ||
514 | + CCU_PARENT_HW(slow_uart1_14p74), | ||
515 | + CCU_PARENT_HW(slow_uart2_48), | ||
516 | +}; | ||
517 | +CCU_MUX_GATE_DEFINE(uart0_clk, uart_clk_parents, APBC_UART1_CLK_RST, 4, 3, | ||
518 | + BIT(1), CLK_IS_CRITICAL); | ||
519 | +CCU_MUX_GATE_DEFINE(uart2_clk, uart_clk_parents, APBC_UART2_CLK_RST, 4, 3, | ||
520 | + BIT(1), 0); | ||
521 | +CCU_MUX_GATE_DEFINE(uart3_clk, uart_clk_parents, APBC_UART3_CLK_RST, 4, 3, | ||
522 | + BIT(1), 0); | ||
523 | +CCU_MUX_GATE_DEFINE(uart4_clk, uart_clk_parents, APBC_UART4_CLK_RST, 4, 3, | ||
524 | + BIT(1), 0); | ||
525 | +CCU_MUX_GATE_DEFINE(uart5_clk, uart_clk_parents, APBC_UART5_CLK_RST, 4, 3, | ||
526 | + BIT(1), 0); | ||
527 | +CCU_MUX_GATE_DEFINE(uart6_clk, uart_clk_parents, APBC_UART6_CLK_RST, 4, 3, | ||
528 | + BIT(1), 0); | ||
529 | +CCU_MUX_GATE_DEFINE(uart7_clk, uart_clk_parents, APBC_UART7_CLK_RST, 4, 3, | ||
530 | + BIT(1), 0); | ||
531 | +CCU_MUX_GATE_DEFINE(uart8_clk, uart_clk_parents, APBC_UART8_CLK_RST, 4, 3, | ||
532 | + BIT(1), 0); | ||
533 | +CCU_MUX_GATE_DEFINE(uart9_clk, uart_clk_parents, APBC_UART9_CLK_RST, 4, 3, | ||
534 | + BIT(1), 0); | ||
535 | + | ||
536 | +CCU_GATE_DEFINE(gpio_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_GPIO_CLK_RST, | ||
537 | + BIT(1), 0); | ||
538 | + | ||
539 | +static const struct clk_parent_data pwm_parents[] = { | ||
540 | + CCU_PARENT_HW(pll1_d192_12p8), | ||
541 | + CCU_PARENT_NAME(osc), | ||
542 | +}; | ||
543 | +CCU_MUX_GATE_DEFINE(pwm0_clk, pwm_parents, APBC_PWM0_CLK_RST, 4, 3, BIT(1), 0); | ||
544 | +CCU_MUX_GATE_DEFINE(pwm1_clk, pwm_parents, APBC_PWM1_CLK_RST, 4, 3, BIT(1), 0); | ||
545 | +CCU_MUX_GATE_DEFINE(pwm2_clk, pwm_parents, APBC_PWM2_CLK_RST, 4, 3, BIT(1), 0); | ||
546 | +CCU_MUX_GATE_DEFINE(pwm3_clk, pwm_parents, APBC_PWM3_CLK_RST, 4, 3, BIT(1), 0); | ||
547 | +CCU_MUX_GATE_DEFINE(pwm4_clk, pwm_parents, APBC_PWM4_CLK_RST, 4, 3, BIT(1), 0); | ||
548 | +CCU_MUX_GATE_DEFINE(pwm5_clk, pwm_parents, APBC_PWM5_CLK_RST, 4, 3, BIT(1), 0); | ||
549 | +CCU_MUX_GATE_DEFINE(pwm6_clk, pwm_parents, APBC_PWM6_CLK_RST, 4, 3, BIT(1), 0); | ||
550 | +CCU_MUX_GATE_DEFINE(pwm7_clk, pwm_parents, APBC_PWM7_CLK_RST, 4, 3, BIT(1), 0); | ||
551 | +CCU_MUX_GATE_DEFINE(pwm8_clk, pwm_parents, APBC_PWM8_CLK_RST, 4, 3, BIT(1), 0); | ||
552 | +CCU_MUX_GATE_DEFINE(pwm9_clk, pwm_parents, APBC_PWM9_CLK_RST, 4, 3, BIT(1), 0); | ||
553 | +CCU_MUX_GATE_DEFINE(pwm10_clk, pwm_parents, APBC_PWM10_CLK_RST, 4, 3, BIT(1), | ||
554 | + 0); | ||
555 | +CCU_MUX_GATE_DEFINE(pwm11_clk, pwm_parents, APBC_PWM11_CLK_RST, 4, 3, BIT(1), | ||
556 | + 0); | ||
557 | +CCU_MUX_GATE_DEFINE(pwm12_clk, pwm_parents, APBC_PWM12_CLK_RST, 4, 3, BIT(1), | ||
558 | + 0); | ||
559 | +CCU_MUX_GATE_DEFINE(pwm13_clk, pwm_parents, APBC_PWM13_CLK_RST, 4, 3, BIT(1), | ||
560 | + 0); | ||
561 | +CCU_MUX_GATE_DEFINE(pwm14_clk, pwm_parents, APBC_PWM14_CLK_RST, 4, 3, BIT(1), | ||
562 | + 0); | ||
563 | +CCU_MUX_GATE_DEFINE(pwm15_clk, pwm_parents, APBC_PWM15_CLK_RST, 4, 3, BIT(1), | ||
564 | + 0); | ||
565 | +CCU_MUX_GATE_DEFINE(pwm16_clk, pwm_parents, APBC_PWM16_CLK_RST, 4, 3, BIT(1), | ||
566 | + 0); | ||
567 | +CCU_MUX_GATE_DEFINE(pwm17_clk, pwm_parents, APBC_PWM17_CLK_RST, 4, 3, BIT(1), | ||
568 | + 0); | ||
569 | +CCU_MUX_GATE_DEFINE(pwm18_clk, pwm_parents, APBC_PWM18_CLK_RST, 4, 3, BIT(1), | ||
570 | + 0); | ||
571 | +CCU_MUX_GATE_DEFINE(pwm19_clk, pwm_parents, APBC_PWM19_CLK_RST, 4, 3, BIT(1), | ||
572 | + 0); | ||
573 | + | ||
574 | +static const struct clk_parent_data ssp_parents[] = { | ||
575 | + CCU_PARENT_HW(pll1_d384_6p4), | ||
576 | + CCU_PARENT_HW(pll1_d192_12p8), | ||
577 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
578 | + CCU_PARENT_HW(pll1_d48_51p2), | ||
579 | + CCU_PARENT_HW(pll1_d768_3p2), | ||
580 | + CCU_PARENT_HW(pll1_d1536_1p6), | ||
581 | + CCU_PARENT_HW(pll1_d3072_0p8), | ||
582 | +}; | ||
583 | +CCU_MUX_GATE_DEFINE(ssp3_clk, ssp_parents, APBC_SSP3_CLK_RST, 4, 3, BIT(1), 0); | ||
584 | + | ||
585 | +CCU_GATE_DEFINE(rtc_clk, CCU_PARENT_NAME(osc), APBC_RTC_CLK_RST, | ||
586 | + BIT(7) | BIT(1), 0); | ||
587 | + | ||
588 | +static const struct clk_parent_data twsi_parents[] = { | ||
589 | + CCU_PARENT_HW(pll1_d78_31p5), | ||
590 | + CCU_PARENT_HW(pll1_d48_51p2), | ||
591 | + CCU_PARENT_HW(pll1_d40_61p44), | ||
592 | +}; | ||
593 | +CCU_MUX_GATE_DEFINE(twsi0_clk, twsi_parents, APBC_TWSI0_CLK_RST, 4, 3, BIT(1), | ||
594 | + 0); | ||
595 | +CCU_MUX_GATE_DEFINE(twsi1_clk, twsi_parents, APBC_TWSI1_CLK_RST, 4, 3, BIT(1), | ||
596 | + 0); | ||
597 | +CCU_MUX_GATE_DEFINE(twsi2_clk, twsi_parents, APBC_TWSI2_CLK_RST, 4, 3, BIT(1), | ||
598 | + 0); | ||
599 | +CCU_MUX_GATE_DEFINE(twsi4_clk, twsi_parents, APBC_TWSI4_CLK_RST, 4, 3, BIT(1), | ||
600 | + 0); | ||
601 | +CCU_MUX_GATE_DEFINE(twsi5_clk, twsi_parents, APBC_TWSI5_CLK_RST, 4, 3, BIT(1), | ||
602 | + 0); | ||
603 | +CCU_MUX_GATE_DEFINE(twsi6_clk, twsi_parents, APBC_TWSI6_CLK_RST, 4, 3, BIT(1), | ||
604 | + 0); | ||
605 | +CCU_MUX_GATE_DEFINE(twsi7_clk, twsi_parents, APBC_TWSI7_CLK_RST, 4, 3, BIT(1), | ||
606 | + 0); | ||
607 | + | ||
608 | +static const struct clk_parent_data timer_parents[] = { | ||
609 | + CCU_PARENT_HW(pll1_d192_12p8), | ||
610 | + CCU_PARENT_NAME(osc), | ||
611 | + CCU_PARENT_HW(pll1_d384_6p4), | ||
612 | + CCU_PARENT_NAME(vctcxo_3m), | ||
613 | + CCU_PARENT_NAME(vctcxo_1m), | ||
614 | +}; | ||
615 | +CCU_MUX_GATE_DEFINE(timers1_clk, timer_parents, APBC_TIMERS1_CLK_RST, 4, 3, | ||
616 | + BIT(1), 0); | ||
617 | +CCU_MUX_GATE_DEFINE(timers2_clk, timer_parents, APBC_TIMERS2_CLK_RST, 4, 3, | ||
618 | + BIT(1), 0); | ||
619 | + | ||
620 | +CCU_GATE_DEFINE(aib_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_AIB_CLK_RST, BIT(1), | ||
621 | + 0); | ||
622 | + | ||
623 | +CCU_GATE_DEFINE(onewire_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_ONEWIRE_CLK_RST, | ||
624 | + BIT(1), 0); | ||
625 | + | ||
626 | +static const struct clk_parent_data sspa_parents[] = { | ||
627 | + CCU_PARENT_HW(pll1_d384_6p4), | ||
628 | + CCU_PARENT_HW(pll1_d192_12p8), | ||
629 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
630 | + CCU_PARENT_HW(pll1_d48_51p2), | ||
631 | + CCU_PARENT_HW(pll1_d768_3p2), | ||
632 | + CCU_PARENT_HW(pll1_d1536_1p6), | ||
633 | + CCU_PARENT_HW(pll1_d3072_0p8), | ||
634 | + CCU_PARENT_HW(i2s_bclk), | ||
635 | +}; | ||
636 | +CCU_MUX_GATE_DEFINE(sspa0_clk, sspa_parents, APBC_SSPA0_CLK_RST, 4, 3, BIT(1), | ||
637 | + 0); | ||
638 | +CCU_MUX_GATE_DEFINE(sspa1_clk, sspa_parents, APBC_SSPA1_CLK_RST, 4, 3, BIT(1), | ||
639 | + 0); | ||
640 | +CCU_GATE_DEFINE(dro_clk, CCU_PARENT_HW(apb_clk), APBC_DRO_CLK_RST, BIT(1), 0); | ||
641 | +CCU_GATE_DEFINE(ir_clk, CCU_PARENT_HW(apb_clk), APBC_IR_CLK_RST, BIT(1), 0); | ||
642 | +CCU_GATE_DEFINE(tsen_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, BIT(1), 0); | ||
643 | +CCU_GATE_DEFINE(ipc_ap2aud_clk, CCU_PARENT_HW(apb_clk), APBC_IPC_AP2AUD_CLK_RST, | ||
644 | + BIT(1), 0); | ||
645 | + | ||
646 | +static const struct clk_parent_data can_parents[] = { | ||
647 | + CCU_PARENT_HW(pll3_20), | ||
648 | + CCU_PARENT_HW(pll3_40), | ||
649 | + CCU_PARENT_HW(pll3_80), | ||
650 | +}; | ||
651 | +CCU_MUX_GATE_DEFINE(can0_clk, can_parents, APBC_CAN0_CLK_RST, 4, 3, BIT(1), 0); | ||
652 | +CCU_GATE_DEFINE(can0_bus_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_CAN0_CLK_RST, | ||
653 | + BIT(0), 0); | ||
654 | + | ||
655 | +CCU_GATE_DEFINE(uart0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART1_CLK_RST, | ||
656 | + BIT(0), CLK_IS_CRITICAL); | ||
657 | +CCU_GATE_DEFINE(uart2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART2_CLK_RST, | ||
658 | + BIT(0), 0); | ||
659 | +CCU_GATE_DEFINE(uart3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART3_CLK_RST, | ||
660 | + BIT(0), 0); | ||
661 | +CCU_GATE_DEFINE(uart4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART4_CLK_RST, | ||
662 | + BIT(0), 0); | ||
663 | +CCU_GATE_DEFINE(uart5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART5_CLK_RST, | ||
664 | + BIT(0), 0); | ||
665 | +CCU_GATE_DEFINE(uart6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART6_CLK_RST, | ||
666 | + BIT(0), 0); | ||
667 | +CCU_GATE_DEFINE(uart7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART7_CLK_RST, | ||
668 | + BIT(0), 0); | ||
669 | +CCU_GATE_DEFINE(uart8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART8_CLK_RST, | ||
670 | + BIT(0), 0); | ||
671 | +CCU_GATE_DEFINE(uart9_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART9_CLK_RST, | ||
672 | + BIT(0), 0); | ||
673 | + | ||
674 | +CCU_GATE_DEFINE(gpio_bus_clk, CCU_PARENT_HW(apb_clk), APBC_GPIO_CLK_RST, BIT(0), | ||
675 | + 0); | ||
676 | + | ||
677 | +CCU_GATE_DEFINE(pwm0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM0_CLK_RST, BIT(0), | ||
678 | + 0); | ||
679 | +CCU_GATE_DEFINE(pwm1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM1_CLK_RST, BIT(0), | ||
680 | + 0); | ||
681 | +CCU_GATE_DEFINE(pwm2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM2_CLK_RST, BIT(0), | ||
682 | + 0); | ||
683 | +CCU_GATE_DEFINE(pwm3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM3_CLK_RST, BIT(0), | ||
684 | + 0); | ||
685 | +CCU_GATE_DEFINE(pwm4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM4_CLK_RST, BIT(0), | ||
686 | + 0); | ||
687 | +CCU_GATE_DEFINE(pwm5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM5_CLK_RST, BIT(0), | ||
688 | + 0); | ||
689 | +CCU_GATE_DEFINE(pwm6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM6_CLK_RST, BIT(0), | ||
690 | + 0); | ||
691 | +CCU_GATE_DEFINE(pwm7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM7_CLK_RST, BIT(0), | ||
692 | + 0); | ||
693 | +CCU_GATE_DEFINE(pwm8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM8_CLK_RST, BIT(0), | ||
694 | + 0); | ||
695 | +CCU_GATE_DEFINE(pwm9_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM9_CLK_RST, BIT(0), | ||
696 | + 0); | ||
697 | +CCU_GATE_DEFINE(pwm10_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM10_CLK_RST, | ||
698 | + BIT(0), 0); | ||
699 | +CCU_GATE_DEFINE(pwm11_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM11_CLK_RST, | ||
700 | + BIT(0), 0); | ||
701 | +CCU_GATE_DEFINE(pwm12_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM12_CLK_RST, | ||
702 | + BIT(0), 0); | ||
703 | +CCU_GATE_DEFINE(pwm13_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM13_CLK_RST, | ||
704 | + BIT(0), 0); | ||
705 | +CCU_GATE_DEFINE(pwm14_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM14_CLK_RST, | ||
706 | + BIT(0), 0); | ||
707 | +CCU_GATE_DEFINE(pwm15_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM15_CLK_RST, | ||
708 | + BIT(0), 0); | ||
709 | +CCU_GATE_DEFINE(pwm16_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM16_CLK_RST, | ||
710 | + BIT(0), 0); | ||
711 | +CCU_GATE_DEFINE(pwm17_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM17_CLK_RST, | ||
712 | + BIT(0), 0); | ||
713 | +CCU_GATE_DEFINE(pwm18_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM18_CLK_RST, | ||
714 | + BIT(0), 0); | ||
715 | +CCU_GATE_DEFINE(pwm19_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM19_CLK_RST, | ||
716 | + BIT(0), 0); | ||
717 | + | ||
718 | +CCU_GATE_DEFINE(ssp3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSP3_CLK_RST, BIT(0), | ||
719 | + 0); | ||
720 | + | ||
721 | +CCU_GATE_DEFINE(rtc_bus_clk, CCU_PARENT_HW(apb_clk), APBC_RTC_CLK_RST, BIT(0), | ||
722 | + 0); | ||
723 | + | ||
724 | +CCU_GATE_DEFINE(twsi0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI0_CLK_RST, | ||
725 | + BIT(0), 0); | ||
726 | +CCU_GATE_DEFINE(twsi1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI1_CLK_RST, | ||
727 | + BIT(0), 0); | ||
728 | +CCU_GATE_DEFINE(twsi2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI2_CLK_RST, | ||
729 | + BIT(0), 0); | ||
730 | +CCU_GATE_DEFINE(twsi4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI4_CLK_RST, | ||
731 | + BIT(0), 0); | ||
732 | +CCU_GATE_DEFINE(twsi5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI5_CLK_RST, | ||
733 | + BIT(0), 0); | ||
734 | +CCU_GATE_DEFINE(twsi6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI6_CLK_RST, | ||
735 | + BIT(0), 0); | ||
736 | +CCU_GATE_DEFINE(twsi7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI7_CLK_RST, | ||
737 | + BIT(0), 0); | ||
738 | + | ||
739 | +CCU_GATE_DEFINE(timers1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS1_CLK_RST, | ||
740 | + BIT(0), 0); | ||
741 | +CCU_GATE_DEFINE(timers2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS2_CLK_RST, | ||
742 | + BIT(0), 0); | ||
743 | + | ||
744 | +CCU_GATE_DEFINE(aib_bus_clk, CCU_PARENT_HW(apb_clk), APBC_AIB_CLK_RST, BIT(0), | ||
745 | + 0); | ||
746 | + | ||
747 | +CCU_GATE_DEFINE(onewire_bus_clk, CCU_PARENT_HW(apb_clk), APBC_ONEWIRE_CLK_RST, | ||
748 | + BIT(0), 0); | ||
749 | + | ||
750 | +CCU_GATE_DEFINE(sspa0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA0_CLK_RST, | ||
751 | + BIT(0), 0); | ||
752 | +CCU_GATE_DEFINE(sspa1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA1_CLK_RST, | ||
753 | + BIT(0), 0); | ||
754 | + | ||
755 | +CCU_GATE_DEFINE(tsen_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, BIT(0), | ||
756 | + 0); | ||
757 | + | ||
758 | +CCU_GATE_DEFINE(ipc_ap2aud_bus_clk, CCU_PARENT_HW(apb_clk), | ||
759 | + APBC_IPC_AP2AUD_CLK_RST, BIT(0), 0); | ||
760 | +/* APBC clocks end */ | ||
761 | + | ||
762 | +/* APMU clocks start */ | ||
763 | +static const struct clk_parent_data pmua_aclk_parents[] = { | ||
764 | + CCU_PARENT_HW(pll1_d10_245p76), | ||
765 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
766 | +}; | ||
767 | +CCU_MUX_DIV_FC_DEFINE(pmua_aclk, pmua_aclk_parents, APMU_ACLK_CLK_CTRL, 1, 2, | ||
768 | + BIT(4), 0, 1, 0); | ||
769 | + | ||
770 | +static const struct clk_parent_data cci550_clk_parents[] = { | ||
771 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
772 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
773 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
774 | + CCU_PARENT_HW(pll2_d3), | ||
775 | +}; | ||
776 | +CCU_MUX_DIV_FC_DEFINE(cci550_clk, cci550_clk_parents, APMU_CCI550_CLK_CTRL, 8, | ||
777 | + 3, BIT(12), 0, 2, CLK_IS_CRITICAL); | ||
778 | + | ||
779 | +static const struct clk_parent_data cpu_c0_hi_clk_parents[] = { | ||
780 | + CCU_PARENT_HW(pll3_d2), | ||
781 | + CCU_PARENT_HW(pll3_d1), | ||
782 | +}; | ||
783 | +CCU_MUX_DEFINE(cpu_c0_hi_clk, cpu_c0_hi_clk_parents, APMU_CPU_C0_CLK_CTRL, 13, | ||
784 | + 1, 0); | ||
785 | +static const struct clk_parent_data cpu_c0_clk_parents[] = { | ||
786 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
787 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
788 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
789 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
790 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
791 | + CCU_PARENT_HW(pll3_d3), | ||
792 | + CCU_PARENT_HW(pll2_d3), | ||
793 | + CCU_PARENT_HW(cpu_c0_hi_clk), | ||
794 | +}; | ||
795 | +CCU_MUX_FC_DEFINE(cpu_c0_core_clk, cpu_c0_clk_parents, APMU_CPU_C0_CLK_CTRL, | ||
796 | + BIT(12), 0, 3, CLK_IS_CRITICAL); | ||
797 | +CCU_DIV_DEFINE(cpu_c0_ace_clk, CCU_PARENT_HW(cpu_c0_core_clk), | ||
798 | + APMU_CPU_C0_CLK_CTRL, 6, 3, CLK_IS_CRITICAL); | ||
799 | +CCU_DIV_DEFINE(cpu_c0_tcm_clk, CCU_PARENT_HW(cpu_c0_core_clk), | ||
800 | + APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL); | ||
801 | + | ||
802 | +static const struct clk_parent_data cpu_c1_hi_clk_parents[] = { | ||
803 | + CCU_PARENT_HW(pll3_d2), | ||
804 | + CCU_PARENT_HW(pll3_d1), | ||
805 | +}; | ||
806 | +CCU_MUX_DEFINE(cpu_c1_hi_clk, cpu_c1_hi_clk_parents, APMU_CPU_C1_CLK_CTRL, 13, | ||
807 | + 1, CLK_IS_CRITICAL); | ||
808 | +static const struct clk_parent_data cpu_c1_clk_parents[] = { | ||
809 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
810 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
811 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
812 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
813 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
814 | + CCU_PARENT_HW(pll3_d3), | ||
815 | + CCU_PARENT_HW(pll2_d3), | ||
816 | + CCU_PARENT_HW(cpu_c1_hi_clk), | ||
817 | +}; | ||
818 | +CCU_MUX_FC_DEFINE(cpu_c1_core_clk, cpu_c1_clk_parents, APMU_CPU_C1_CLK_CTRL, | ||
819 | + BIT(12), 0, 3, CLK_IS_CRITICAL); | ||
820 | +CCU_DIV_DEFINE(cpu_c1_ace_clk, CCU_PARENT_HW(cpu_c1_core_clk), | ||
821 | + APMU_CPU_C1_CLK_CTRL, 6, 3, CLK_IS_CRITICAL); | ||
822 | + | ||
823 | +static const struct clk_parent_data jpg_parents[] = { | ||
824 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
825 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
826 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
827 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
828 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
829 | + CCU_PARENT_HW(pll2_d4), | ||
830 | + CCU_PARENT_HW(pll2_d3), | ||
831 | +}; | ||
832 | +CCU_MUX_DIV_GATE_FC_DEFINE(jpg_clk, jpg_parents, APMU_JPG_CLK_RES_CTRL, 5, 3, | ||
833 | + BIT(15), 2, 3, BIT(1), 0); | ||
834 | + | ||
835 | +static const struct clk_parent_data ccic2phy_parents[] = { | ||
836 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
837 | + CCU_PARENT_HW(pll1_d48_51p2_ap), | ||
838 | +}; | ||
839 | +CCU_MUX_GATE_DEFINE(ccic2phy_clk, ccic2phy_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
840 | + 7, 1, BIT(5), 0); | ||
841 | + | ||
842 | +static const struct clk_parent_data ccic3phy_parents[] = { | ||
843 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
844 | + CCU_PARENT_HW(pll1_d48_51p2_ap), | ||
845 | +}; | ||
846 | +CCU_MUX_GATE_DEFINE(ccic3phy_clk, ccic3phy_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
847 | + 31, 1, BIT(30), 0); | ||
848 | + | ||
849 | +static const struct clk_parent_data csi_parents[] = { | ||
850 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
851 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
852 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
853 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
854 | + CCU_PARENT_HW(pll2_d2), | ||
855 | + CCU_PARENT_HW(pll2_d3), | ||
856 | + CCU_PARENT_HW(pll2_d4), | ||
857 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
858 | +}; | ||
859 | +CCU_MUX_DIV_GATE_FC_DEFINE(csi_clk, csi_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
860 | + 20, 3, BIT(15), 16, 3, BIT(4), 0); | ||
861 | + | ||
862 | +static const struct clk_parent_data camm_parents[] = { | ||
863 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
864 | + CCU_PARENT_HW(pll2_d5), | ||
865 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
866 | + CCU_PARENT_NAME(vctcxo_24m), | ||
867 | +}; | ||
868 | +CCU_MUX_DIV_GATE_DEFINE(camm0_clk, camm_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
869 | + 23, 4, 8, 2, BIT(28), 0); | ||
870 | +CCU_MUX_DIV_GATE_DEFINE(camm1_clk, camm_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
871 | + 23, 4, 8, 2, BIT(6), 0); | ||
872 | +CCU_MUX_DIV_GATE_DEFINE(camm2_clk, camm_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, | ||
873 | + 23, 4, 8, 2, BIT(3), 0); | ||
874 | + | ||
875 | +static const struct clk_parent_data isp_cpp_parents[] = { | ||
876 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
877 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
878 | +}; | ||
879 | +CCU_MUX_DIV_GATE_DEFINE(isp_cpp_clk, isp_cpp_parents, APMU_ISP_CLK_RES_CTRL, 24, | ||
880 | + 2, 26, 1, BIT(28), 0); | ||
881 | +static const struct clk_parent_data isp_bus_parents[] = { | ||
882 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
883 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
884 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
885 | + CCU_PARENT_HW(pll1_d10_245p76), | ||
886 | +}; | ||
887 | +CCU_MUX_DIV_GATE_FC_DEFINE(isp_bus_clk, isp_bus_parents, APMU_ISP_CLK_RES_CTRL, | ||
888 | + 18, 3, BIT(23), 21, 2, BIT(17), 0); | ||
889 | +static const struct clk_parent_data isp_parents[] = { | ||
890 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
891 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
892 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
893 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
894 | +}; | ||
895 | +CCU_MUX_DIV_GATE_FC_DEFINE(isp_clk, isp_parents, APMU_ISP_CLK_RES_CTRL, 4, 3, | ||
896 | + BIT(7), 8, 2, BIT(1), 0); | ||
897 | + | ||
898 | +static const struct clk_parent_data dpumclk_parents[] = { | ||
899 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
900 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
901 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
902 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
903 | +}; | ||
904 | +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dpu_mclk, dpumclk_parents, | ||
905 | + APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1, | ||
906 | + 1, 4, BIT(29), 5, 3, BIT(0), 0); | ||
907 | + | ||
908 | +static const struct clk_parent_data dpuesc_parents[] = { | ||
909 | + CCU_PARENT_HW(pll1_d48_51p2_ap), | ||
910 | + CCU_PARENT_HW(pll1_d52_47p26), | ||
911 | + CCU_PARENT_HW(pll1_d96_25p6), | ||
912 | + CCU_PARENT_HW(pll1_d32_76p8), | ||
913 | +}; | ||
914 | +CCU_MUX_GATE_DEFINE(dpu_esc_clk, dpuesc_parents, APMU_LCD_CLK_RES_CTRL1, 0, 2, | ||
915 | + BIT(2), 0); | ||
916 | + | ||
917 | +static const struct clk_parent_data dpubit_parents[] = { | ||
918 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
919 | + CCU_PARENT_HW(pll2_d2), | ||
920 | + CCU_PARENT_HW(pll2_d3), | ||
921 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
922 | + CCU_PARENT_HW(pll2_d4), | ||
923 | + CCU_PARENT_HW(pll2_d5), | ||
924 | + CCU_PARENT_HW(pll2_d7), | ||
925 | + CCU_PARENT_HW(pll2_d8), | ||
926 | +}; | ||
927 | +CCU_MUX_DIV_GATE_FC_DEFINE(dpu_bit_clk, dpubit_parents, APMU_LCD_CLK_RES_CTRL1, | ||
928 | + 17, 3, BIT(31), 20, 3, BIT(16), 0); | ||
929 | + | ||
930 | +static const struct clk_parent_data dpupx_parents[] = { | ||
931 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
932 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
933 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
934 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
935 | + CCU_PARENT_HW(pll2_d7), | ||
936 | + CCU_PARENT_HW(pll2_d8), | ||
937 | +}; | ||
938 | +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dpu_pxclk, dpupx_parents, | ||
939 | + APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1, | ||
940 | + 17, 4, BIT(30), 21, 3, BIT(16), 0); | ||
941 | + | ||
942 | +CCU_GATE_DEFINE(dpu_hclk, CCU_PARENT_HW(pmua_aclk), APMU_LCD_CLK_RES_CTRL1, | ||
943 | + BIT(5), 0); | ||
944 | + | ||
945 | +static const struct clk_parent_data dpu_spi_parents[] = { | ||
946 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
947 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
948 | + CCU_PARENT_HW(pll1_d10_245p76), | ||
949 | + CCU_PARENT_HW(pll1_d11_223p4), | ||
950 | + CCU_PARENT_HW(pll1_d13_189), | ||
951 | + CCU_PARENT_HW(pll1_d23_106p8), | ||
952 | + CCU_PARENT_HW(pll2_d3), | ||
953 | + CCU_PARENT_HW(pll2_d5), | ||
954 | +}; | ||
955 | +CCU_MUX_DIV_GATE_FC_DEFINE(dpu_spi_clk, dpu_spi_parents, | ||
956 | + APMU_LCD_SPI_CLK_RES_CTRL, 8, 3, BIT(7), 12, 3, | ||
957 | + BIT(1), 0); | ||
958 | +CCU_GATE_DEFINE(dpu_spi_hbus_clk, CCU_PARENT_HW(pmua_aclk), | ||
959 | + APMU_LCD_SPI_CLK_RES_CTRL, BIT(3), 0); | ||
960 | +CCU_GATE_DEFINE(dpu_spi_bus_clk, CCU_PARENT_HW(pmua_aclk), | ||
961 | + APMU_LCD_SPI_CLK_RES_CTRL, BIT(5), 0); | ||
962 | +CCU_GATE_DEFINE(dpu_spi_aclk, CCU_PARENT_HW(pmua_aclk), | ||
963 | + APMU_LCD_SPI_CLK_RES_CTRL, BIT(6), 0); | ||
964 | + | ||
965 | +static const struct clk_parent_data v2d_parents[] = { | ||
966 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
967 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
968 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
969 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
970 | +}; | ||
971 | +CCU_MUX_DIV_GATE_FC_DEFINE(v2d_clk, v2d_parents, APMU_LCD_CLK_RES_CTRL1, 9, 3, | ||
972 | + BIT(28), 12, 2, BIT(8), 0); | ||
973 | + | ||
974 | +static const struct clk_parent_data ccic_4x_parents[] = { | ||
975 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
976 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
977 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
978 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
979 | + CCU_PARENT_HW(pll2_d2), | ||
980 | + CCU_PARENT_HW(pll2_d3), | ||
981 | + CCU_PARENT_HW(pll2_d4), | ||
982 | + CCU_PARENT_HW(pll1_d2_1228p8), | ||
983 | +}; | ||
984 | +CCU_MUX_DIV_GATE_FC_DEFINE(ccic_4x_clk, ccic_4x_parents, APMU_CCIC_CLK_RES_CTRL, | ||
985 | + 18, 3, BIT(15), 23, 2, BIT(4), 0); | ||
986 | + | ||
987 | +static const struct clk_parent_data ccic1phy_parents[] = { | ||
988 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
989 | + CCU_PARENT_HW(pll1_d48_51p2_ap), | ||
990 | +}; | ||
991 | +CCU_MUX_GATE_DEFINE(ccic1phy_clk, ccic1phy_parents, APMU_CCIC_CLK_RES_CTRL, 7, | ||
992 | + 1, BIT(5), 0); | ||
993 | + | ||
994 | +CCU_GATE_DEFINE(sdh_axi_aclk, CCU_PARENT_HW(pmua_aclk), APMU_SDH0_CLK_RES_CTRL, | ||
995 | + BIT(3), 0); | ||
996 | +static const struct clk_parent_data sdh01_parents[] = { | ||
997 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
998 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
999 | + CCU_PARENT_HW(pll2_d8), | ||
1000 | + CCU_PARENT_HW(pll2_d5), | ||
1001 | + CCU_PARENT_HW(pll1_d11_223p4), | ||
1002 | + CCU_PARENT_HW(pll1_d13_189), | ||
1003 | + CCU_PARENT_HW(pll1_d23_106p8), | ||
1004 | +}; | ||
1005 | +CCU_MUX_DIV_GATE_FC_DEFINE(sdh0_clk, sdh01_parents, APMU_SDH0_CLK_RES_CTRL, 8, | ||
1006 | + 3, BIT(11), 5, 3, BIT(4), 0); | ||
1007 | +CCU_MUX_DIV_GATE_FC_DEFINE(sdh1_clk, sdh01_parents, APMU_SDH1_CLK_RES_CTRL, 8, | ||
1008 | + 3, BIT(11), 5, 3, BIT(4), 0); | ||
1009 | +static const struct clk_parent_data sdh2_parents[] = { | ||
1010 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1011 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1012 | + CCU_PARENT_HW(pll2_d8), | ||
1013 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1014 | + CCU_PARENT_HW(pll1_d11_223p4), | ||
1015 | + CCU_PARENT_HW(pll1_d13_189), | ||
1016 | + CCU_PARENT_HW(pll1_d23_106p8), | ||
1017 | +}; | ||
1018 | +CCU_MUX_DIV_GATE_FC_DEFINE(sdh2_clk, sdh2_parents, APMU_SDH2_CLK_RES_CTRL, 8, 3, | ||
1019 | + BIT(11), 5, 3, BIT(4), 0); | ||
1020 | + | ||
1021 | +CCU_GATE_DEFINE(usb_axi_clk, CCU_PARENT_HW(pmua_aclk), APMU_USB_CLK_RES_CTRL, | ||
1022 | + BIT(1), 0); | ||
1023 | +CCU_GATE_DEFINE(usb_p1_aclk, CCU_PARENT_HW(pmua_aclk), APMU_USB_CLK_RES_CTRL, | ||
1024 | + BIT(5), 0); | ||
1025 | +CCU_GATE_DEFINE(usb30_clk, CCU_PARENT_HW(pmua_aclk), APMU_USB_CLK_RES_CTRL, | ||
1026 | + BIT(8), 0); | ||
1027 | + | ||
1028 | +static const struct clk_parent_data qspi_parents[] = { | ||
1029 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1030 | + CCU_PARENT_HW(pll2_d8), | ||
1031 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1032 | + CCU_PARENT_HW(pll1_d10_245p76), | ||
1033 | + CCU_PARENT_HW(pll1_d11_223p4), | ||
1034 | + CCU_PARENT_HW(pll1_d23_106p8), | ||
1035 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1036 | + CCU_PARENT_HW(pll1_d13_189), | ||
1037 | +}; | ||
1038 | +CCU_MUX_DIV_GATE_FC_DEFINE(qspi_clk, qspi_parents, APMU_QSPI_CLK_RES_CTRL, 9, 3, | ||
1039 | + BIT(12), 6, 3, BIT(4), 0); | ||
1040 | +CCU_GATE_DEFINE(qspi_bus_clk, CCU_PARENT_HW(pmua_aclk), APMU_QSPI_CLK_RES_CTRL, | ||
1041 | + BIT(3), 0); | ||
1042 | +CCU_GATE_DEFINE(dma_clk, CCU_PARENT_HW(pmua_aclk), APMU_DMA_CLK_RES_CTRL, | ||
1043 | + BIT(3), 0); | ||
1044 | + | ||
1045 | +static const struct clk_parent_data aes_parents[] = { | ||
1046 | + CCU_PARENT_HW(pll1_d12_204p8), | ||
1047 | + CCU_PARENT_HW(pll1_d24_102p4), | ||
1048 | +}; | ||
1049 | +CCU_MUX_GATE_DEFINE(aes_clk, aes_parents, APMU_AES_CLK_RES_CTRL, 6, 1, BIT(5), | ||
1050 | + 0); | ||
1051 | + | ||
1052 | +static const struct clk_parent_data vpu_parents[] = { | ||
1053 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1054 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1055 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1056 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1057 | + CCU_PARENT_HW(pll3_d6), | ||
1058 | + CCU_PARENT_HW(pll2_d3), | ||
1059 | + CCU_PARENT_HW(pll2_d4), | ||
1060 | + CCU_PARENT_HW(pll2_d5), | ||
1061 | +}; | ||
1062 | +CCU_MUX_DIV_GATE_FC_DEFINE(vpu_clk, vpu_parents, APMU_VPU_CLK_RES_CTRL, 13, 3, | ||
1063 | + BIT(21), 10, 3, BIT(3), 0); | ||
1064 | + | ||
1065 | +static const struct clk_parent_data gpu_parents[] = { | ||
1066 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1067 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1068 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1069 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1070 | + CCU_PARENT_HW(pll3_d6), | ||
1071 | + CCU_PARENT_HW(pll2_d3), | ||
1072 | + CCU_PARENT_HW(pll2_d4), | ||
1073 | + CCU_PARENT_HW(pll2_d5), | ||
1074 | +}; | ||
1075 | +CCU_MUX_DIV_GATE_FC_DEFINE(gpu_clk, gpu_parents, APMU_GPU_CLK_RES_CTRL, 12, 3, | ||
1076 | + BIT(15), 18, 3, BIT(4), 0); | ||
1077 | + | ||
1078 | +static const struct clk_parent_data emmc_parents[] = { | ||
1079 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1080 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1081 | + CCU_PARENT_HW(pll1_d52_47p26), | ||
1082 | + CCU_PARENT_HW(pll1_d3_819p2), | ||
1083 | +}; | ||
1084 | +CCU_MUX_DIV_GATE_FC_DEFINE(emmc_clk, emmc_parents, APMU_PMUA_EM_CLK_RES_CTRL, | ||
1085 | + 8, 3, BIT(11), 6, 2, BIT(4), 0); | ||
1086 | +CCU_DIV_GATE_DEFINE(emmc_x_clk, CCU_PARENT_HW(pll1_d2_1228p8), | ||
1087 | + APMU_PMUA_EM_CLK_RES_CTRL, 12, 3, BIT(15), 0); | ||
1088 | + | ||
1089 | +static const struct clk_parent_data audio_parents[] = { | ||
1090 | + CCU_PARENT_HW(pll1_aud_245p7), | ||
1091 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1092 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1093 | +}; | ||
1094 | +CCU_MUX_DIV_GATE_FC_DEFINE(audio_clk, audio_parents, APMU_AUDIO_CLK_RES_CTRL, 4, | ||
1095 | + 3, BIT(15), 7, 3, BIT(12), 0); | ||
1096 | + | ||
1097 | +static const struct clk_parent_data hdmi_parents[] = { | ||
1098 | + CCU_PARENT_HW(pll1_d6_409p6), | ||
1099 | + CCU_PARENT_HW(pll1_d5_491p52), | ||
1100 | + CCU_PARENT_HW(pll1_d4_614p4), | ||
1101 | + CCU_PARENT_HW(pll1_d8_307p2), | ||
1102 | +}; | ||
1103 | +CCU_MUX_DIV_GATE_FC_DEFINE(hdmi_mclk, hdmi_parents, APMU_HDMI_CLK_RES_CTRL, 1, | ||
1104 | + 4, BIT(29), 5, 3, BIT(0), 0); | ||
1105 | + | ||
1106 | +CCU_GATE_DEFINE(pcie0_master_clk, CCU_PARENT_HW(pmua_aclk), | ||
1107 | + APMU_PCIE_CLK_RES_CTRL_0, BIT(2), 0); | ||
1108 | +CCU_GATE_DEFINE(pcie0_slave_clk, CCU_PARENT_HW(pmua_aclk), | ||
1109 | + APMU_PCIE_CLK_RES_CTRL_0, BIT(1), 0); | ||
1110 | +CCU_GATE_DEFINE(pcie0_dbi_clk, CCU_PARENT_HW(pmua_aclk), | ||
1111 | + APMU_PCIE_CLK_RES_CTRL_0, BIT(0), 0); | ||
1112 | + | ||
1113 | +CCU_GATE_DEFINE(pcie1_master_clk, CCU_PARENT_HW(pmua_aclk), | ||
1114 | + APMU_PCIE_CLK_RES_CTRL_1, BIT(2), 0); | ||
1115 | +CCU_GATE_DEFINE(pcie1_slave_clk, CCU_PARENT_HW(pmua_aclk), | ||
1116 | + APMU_PCIE_CLK_RES_CTRL_1, BIT(1), 0); | ||
1117 | +CCU_GATE_DEFINE(pcie1_dbi_clk, CCU_PARENT_HW(pmua_aclk), | ||
1118 | + APMU_PCIE_CLK_RES_CTRL_1, BIT(0), 0); | ||
1119 | + | ||
1120 | +CCU_GATE_DEFINE(pcie2_master_clk, CCU_PARENT_HW(pmua_aclk), | ||
1121 | + APMU_PCIE_CLK_RES_CTRL_2, BIT(2), 0); | ||
1122 | +CCU_GATE_DEFINE(pcie2_slave_clk, CCU_PARENT_HW(pmua_aclk), | ||
1123 | + APMU_PCIE_CLK_RES_CTRL_2, BIT(1), 0); | ||
1124 | +CCU_GATE_DEFINE(pcie2_dbi_clk, CCU_PARENT_HW(pmua_aclk), | ||
1125 | + APMU_PCIE_CLK_RES_CTRL_2, BIT(0), 0); | ||
1126 | + | ||
1127 | +CCU_GATE_DEFINE(emac0_bus_clk, CCU_PARENT_HW(pmua_aclk), | ||
1128 | + APMU_EMAC0_CLK_RES_CTRL, BIT(0), 0); | ||
1129 | +CCU_GATE_DEFINE(emac0_ptp_clk, CCU_PARENT_HW(pll2_d6), | ||
1130 | + APMU_EMAC0_CLK_RES_CTRL, BIT(15), 0); | ||
1131 | +CCU_GATE_DEFINE(emac1_bus_clk, CCU_PARENT_HW(pmua_aclk), | ||
1132 | + APMU_EMAC1_CLK_RES_CTRL, BIT(0), 0); | ||
1133 | +CCU_GATE_DEFINE(emac1_ptp_clk, CCU_PARENT_HW(pll2_d6), APMU_EMAC1_CLK_RES_CTRL, | ||
1134 | + BIT(15), 0); | ||
1135 | + | ||
1136 | +CCU_GATE_DEFINE(emmc_bus_clk, CCU_PARENT_HW(pmua_aclk), | ||
1137 | + APMU_PMUA_EM_CLK_RES_CTRL, BIT(3), 0); | ||
1138 | +/* APMU clocks end */ | ||
1709 | + | 1139 | + |
1710 | +struct spacemit_ccu_data { | 1140 | +struct spacemit_ccu_data { |
1711 | + struct clk_hw_onecell_data *hw_clks; | 1141 | + struct clk_hw **hws; |
1712 | + bool need_pll_lock; | 1142 | + size_t num; |
1713 | +}; | 1143 | +}; |
1714 | + | 1144 | + |
1715 | +struct spacemit_ccu_priv { | 1145 | +static struct clk_hw *k1_ccu_pll_hws[] = { |
1716 | + const struct spacemit_ccu_data *data; | 1146 | + [CLK_PLL1] = &pll1.common.hw, |
1717 | + struct regmap *base; | 1147 | + [CLK_PLL2] = &pll2.common.hw, |
1718 | + struct regmap *lock_base; | 1148 | + [CLK_PLL3] = &pll3.common.hw, |
1149 | + [CLK_PLL1_D2] = &pll1_d2.common.hw, | ||
1150 | + [CLK_PLL1_D3] = &pll1_d3.common.hw, | ||
1151 | + [CLK_PLL1_D4] = &pll1_d4.common.hw, | ||
1152 | + [CLK_PLL1_D5] = &pll1_d5.common.hw, | ||
1153 | + [CLK_PLL1_D6] = &pll1_d6.common.hw, | ||
1154 | + [CLK_PLL1_D7] = &pll1_d7.common.hw, | ||
1155 | + [CLK_PLL1_D8] = &pll1_d8.common.hw, | ||
1156 | + [CLK_PLL1_D11] = &pll1_d11_223p4.common.hw, | ||
1157 | + [CLK_PLL1_D13] = &pll1_d13_189.common.hw, | ||
1158 | + [CLK_PLL1_D23] = &pll1_d23_106p8.common.hw, | ||
1159 | + [CLK_PLL1_D64] = &pll1_d64_38p4.common.hw, | ||
1160 | + [CLK_PLL1_D10_AUD] = &pll1_aud_245p7.common.hw, | ||
1161 | + [CLK_PLL1_D100_AUD] = &pll1_aud_24p5.common.hw, | ||
1162 | + [CLK_PLL2_D1] = &pll2_d1.common.hw, | ||
1163 | + [CLK_PLL2_D2] = &pll2_d2.common.hw, | ||
1164 | + [CLK_PLL2_D3] = &pll2_d3.common.hw, | ||
1165 | + [CLK_PLL2_D4] = &pll2_d4.common.hw, | ||
1166 | + [CLK_PLL2_D5] = &pll2_d5.common.hw, | ||
1167 | + [CLK_PLL2_D6] = &pll2_d6.common.hw, | ||
1168 | + [CLK_PLL2_D7] = &pll2_d7.common.hw, | ||
1169 | + [CLK_PLL2_D8] = &pll2_d8.common.hw, | ||
1170 | + [CLK_PLL3_D1] = &pll3_d1.common.hw, | ||
1171 | + [CLK_PLL3_D2] = &pll3_d2.common.hw, | ||
1172 | + [CLK_PLL3_D3] = &pll3_d3.common.hw, | ||
1173 | + [CLK_PLL3_D4] = &pll3_d4.common.hw, | ||
1174 | + [CLK_PLL3_D5] = &pll3_d5.common.hw, | ||
1175 | + [CLK_PLL3_D6] = &pll3_d6.common.hw, | ||
1176 | + [CLK_PLL3_D7] = &pll3_d7.common.hw, | ||
1177 | + [CLK_PLL3_D8] = &pll3_d8.common.hw, | ||
1178 | + [CLK_PLL3_80] = &pll3_80.common.hw, | ||
1179 | + [CLK_PLL3_40] = &pll3_40.common.hw, | ||
1180 | + [CLK_PLL3_20] = &pll3_20.common.hw, | ||
1181 | +}; | ||
1182 | + | ||
1183 | +static const struct spacemit_ccu_data k1_ccu_pll_data = { | ||
1184 | + .hws = k1_ccu_pll_hws, | ||
1185 | + .num = ARRAY_SIZE(k1_ccu_pll_hws), | ||
1186 | +}; | ||
1187 | + | ||
1188 | +static struct clk_hw *k1_ccu_mpmu_hws[] = { | ||
1189 | + [CLK_PLL1_307P2] = &pll1_d8_307p2.common.hw, | ||
1190 | + [CLK_PLL1_76P8] = &pll1_d32_76p8.common.hw, | ||
1191 | + [CLK_PLL1_61P44] = &pll1_d40_61p44.common.hw, | ||
1192 | + [CLK_PLL1_153P6] = &pll1_d16_153p6.common.hw, | ||
1193 | + [CLK_PLL1_102P4] = &pll1_d24_102p4.common.hw, | ||
1194 | + [CLK_PLL1_51P2] = &pll1_d48_51p2.common.hw, | ||
1195 | + [CLK_PLL1_51P2_AP] = &pll1_d48_51p2_ap.common.hw, | ||
1196 | + [CLK_PLL1_57P6] = &pll1_m3d128_57p6.common.hw, | ||
1197 | + [CLK_PLL1_25P6] = &pll1_d96_25p6.common.hw, | ||
1198 | + [CLK_PLL1_12P8] = &pll1_d192_12p8.common.hw, | ||
1199 | + [CLK_PLL1_12P8_WDT] = &pll1_d192_12p8_wdt.common.hw, | ||
1200 | + [CLK_PLL1_6P4] = &pll1_d384_6p4.common.hw, | ||
1201 | + [CLK_PLL1_3P2] = &pll1_d768_3p2.common.hw, | ||
1202 | + [CLK_PLL1_1P6] = &pll1_d1536_1p6.common.hw, | ||
1203 | + [CLK_PLL1_0P8] = &pll1_d3072_0p8.common.hw, | ||
1204 | + [CLK_PLL1_409P6] = &pll1_d6_409p6.common.hw, | ||
1205 | + [CLK_PLL1_204P8] = &pll1_d12_204p8.common.hw, | ||
1206 | + [CLK_PLL1_491] = &pll1_d5_491p52.common.hw, | ||
1207 | + [CLK_PLL1_245P76] = &pll1_d10_245p76.common.hw, | ||
1208 | + [CLK_PLL1_614] = &pll1_d4_614p4.common.hw, | ||
1209 | + [CLK_PLL1_47P26] = &pll1_d52_47p26.common.hw, | ||
1210 | + [CLK_PLL1_31P5] = &pll1_d78_31p5.common.hw, | ||
1211 | + [CLK_PLL1_819] = &pll1_d3_819p2.common.hw, | ||
1212 | + [CLK_PLL1_1228] = &pll1_d2_1228p8.common.hw, | ||
1213 | + [CLK_SLOW_UART] = &slow_uart.common.hw, | ||
1214 | + [CLK_SLOW_UART1] = &slow_uart1_14p74.common.hw, | ||
1215 | + [CLK_SLOW_UART2] = &slow_uart2_48.common.hw, | ||
1216 | + [CLK_WDT] = &wdt_clk.common.hw, | ||
1217 | + [CLK_RIPC] = &ripc_clk.common.hw, | ||
1218 | + [CLK_I2S_SYSCLK] = &i2s_sysclk.common.hw, | ||
1219 | + [CLK_I2S_BCLK] = &i2s_bclk.common.hw, | ||
1220 | + [CLK_APB] = &apb_clk.common.hw, | ||
1221 | + [CLK_WDT_BUS] = &wdt_bus_clk.common.hw, | ||
1222 | +}; | ||
1223 | + | ||
1224 | +static const struct spacemit_ccu_data k1_ccu_mpmu_data = { | ||
1225 | + .hws = k1_ccu_mpmu_hws, | ||
1226 | + .num = ARRAY_SIZE(k1_ccu_mpmu_hws), | ||
1227 | +}; | ||
1228 | + | ||
1229 | +static struct clk_hw *k1_ccu_apbc_hws[] = { | ||
1230 | + [CLK_UART0] = &uart0_clk.common.hw, | ||
1231 | + [CLK_UART2] = &uart2_clk.common.hw, | ||
1232 | + [CLK_UART3] = &uart3_clk.common.hw, | ||
1233 | + [CLK_UART4] = &uart4_clk.common.hw, | ||
1234 | + [CLK_UART5] = &uart5_clk.common.hw, | ||
1235 | + [CLK_UART6] = &uart6_clk.common.hw, | ||
1236 | + [CLK_UART7] = &uart7_clk.common.hw, | ||
1237 | + [CLK_UART8] = &uart8_clk.common.hw, | ||
1238 | + [CLK_UART9] = &uart9_clk.common.hw, | ||
1239 | + [CLK_GPIO] = &gpio_clk.common.hw, | ||
1240 | + [CLK_PWM0] = &pwm0_clk.common.hw, | ||
1241 | + [CLK_PWM1] = &pwm1_clk.common.hw, | ||
1242 | + [CLK_PWM2] = &pwm2_clk.common.hw, | ||
1243 | + [CLK_PWM3] = &pwm3_clk.common.hw, | ||
1244 | + [CLK_PWM4] = &pwm4_clk.common.hw, | ||
1245 | + [CLK_PWM5] = &pwm5_clk.common.hw, | ||
1246 | + [CLK_PWM6] = &pwm6_clk.common.hw, | ||
1247 | + [CLK_PWM7] = &pwm7_clk.common.hw, | ||
1248 | + [CLK_PWM8] = &pwm8_clk.common.hw, | ||
1249 | + [CLK_PWM9] = &pwm9_clk.common.hw, | ||
1250 | + [CLK_PWM10] = &pwm10_clk.common.hw, | ||
1251 | + [CLK_PWM11] = &pwm11_clk.common.hw, | ||
1252 | + [CLK_PWM12] = &pwm12_clk.common.hw, | ||
1253 | + [CLK_PWM13] = &pwm13_clk.common.hw, | ||
1254 | + [CLK_PWM14] = &pwm14_clk.common.hw, | ||
1255 | + [CLK_PWM15] = &pwm15_clk.common.hw, | ||
1256 | + [CLK_PWM16] = &pwm16_clk.common.hw, | ||
1257 | + [CLK_PWM17] = &pwm17_clk.common.hw, | ||
1258 | + [CLK_PWM18] = &pwm18_clk.common.hw, | ||
1259 | + [CLK_PWM19] = &pwm19_clk.common.hw, | ||
1260 | + [CLK_SSP3] = &ssp3_clk.common.hw, | ||
1261 | + [CLK_RTC] = &rtc_clk.common.hw, | ||
1262 | + [CLK_TWSI0] = &twsi0_clk.common.hw, | ||
1263 | + [CLK_TWSI1] = &twsi1_clk.common.hw, | ||
1264 | + [CLK_TWSI2] = &twsi2_clk.common.hw, | ||
1265 | + [CLK_TWSI4] = &twsi4_clk.common.hw, | ||
1266 | + [CLK_TWSI5] = &twsi5_clk.common.hw, | ||
1267 | + [CLK_TWSI6] = &twsi6_clk.common.hw, | ||
1268 | + [CLK_TWSI7] = &twsi7_clk.common.hw, | ||
1269 | + [CLK_TIMERS1] = &timers1_clk.common.hw, | ||
1270 | + [CLK_TIMERS2] = &timers2_clk.common.hw, | ||
1271 | + [CLK_AIB] = &aib_clk.common.hw, | ||
1272 | + [CLK_ONEWIRE] = &onewire_clk.common.hw, | ||
1273 | + [CLK_SSPA0] = &sspa0_clk.common.hw, | ||
1274 | + [CLK_SSPA1] = &sspa1_clk.common.hw, | ||
1275 | + [CLK_DRO] = &dro_clk.common.hw, | ||
1276 | + [CLK_IR] = &ir_clk.common.hw, | ||
1277 | + [CLK_TSEN] = &tsen_clk.common.hw, | ||
1278 | + [CLK_IPC_AP2AUD] = &ipc_ap2aud_clk.common.hw, | ||
1279 | + [CLK_CAN0] = &can0_clk.common.hw, | ||
1280 | + [CLK_CAN0_BUS] = &can0_bus_clk.common.hw, | ||
1281 | + [CLK_UART0_BUS] = &uart0_bus_clk.common.hw, | ||
1282 | + [CLK_UART2_BUS] = &uart2_bus_clk.common.hw, | ||
1283 | + [CLK_UART3_BUS] = &uart3_bus_clk.common.hw, | ||
1284 | + [CLK_UART4_BUS] = &uart4_bus_clk.common.hw, | ||
1285 | + [CLK_UART5_BUS] = &uart5_bus_clk.common.hw, | ||
1286 | + [CLK_UART6_BUS] = &uart6_bus_clk.common.hw, | ||
1287 | + [CLK_UART7_BUS] = &uart7_bus_clk.common.hw, | ||
1288 | + [CLK_UART8_BUS] = &uart8_bus_clk.common.hw, | ||
1289 | + [CLK_UART9_BUS] = &uart9_bus_clk.common.hw, | ||
1290 | + [CLK_GPIO_BUS] = &gpio_bus_clk.common.hw, | ||
1291 | + [CLK_PWM0_BUS] = &pwm0_bus_clk.common.hw, | ||
1292 | + [CLK_PWM1_BUS] = &pwm1_bus_clk.common.hw, | ||
1293 | + [CLK_PWM2_BUS] = &pwm2_bus_clk.common.hw, | ||
1294 | + [CLK_PWM3_BUS] = &pwm3_bus_clk.common.hw, | ||
1295 | + [CLK_PWM4_BUS] = &pwm4_bus_clk.common.hw, | ||
1296 | + [CLK_PWM5_BUS] = &pwm5_bus_clk.common.hw, | ||
1297 | + [CLK_PWM6_BUS] = &pwm6_bus_clk.common.hw, | ||
1298 | + [CLK_PWM7_BUS] = &pwm7_bus_clk.common.hw, | ||
1299 | + [CLK_PWM8_BUS] = &pwm8_bus_clk.common.hw, | ||
1300 | + [CLK_PWM9_BUS] = &pwm9_bus_clk.common.hw, | ||
1301 | + [CLK_PWM10_BUS] = &pwm10_bus_clk.common.hw, | ||
1302 | + [CLK_PWM11_BUS] = &pwm11_bus_clk.common.hw, | ||
1303 | + [CLK_PWM12_BUS] = &pwm12_bus_clk.common.hw, | ||
1304 | + [CLK_PWM13_BUS] = &pwm13_bus_clk.common.hw, | ||
1305 | + [CLK_PWM14_BUS] = &pwm14_bus_clk.common.hw, | ||
1306 | + [CLK_PWM15_BUS] = &pwm15_bus_clk.common.hw, | ||
1307 | + [CLK_PWM16_BUS] = &pwm16_bus_clk.common.hw, | ||
1308 | + [CLK_PWM17_BUS] = &pwm17_bus_clk.common.hw, | ||
1309 | + [CLK_PWM18_BUS] = &pwm18_bus_clk.common.hw, | ||
1310 | + [CLK_PWM19_BUS] = &pwm19_bus_clk.common.hw, | ||
1311 | + [CLK_SSP3_BUS] = &ssp3_bus_clk.common.hw, | ||
1312 | + [CLK_RTC_BUS] = &rtc_bus_clk.common.hw, | ||
1313 | + [CLK_TWSI0_BUS] = &twsi0_bus_clk.common.hw, | ||
1314 | + [CLK_TWSI1_BUS] = &twsi1_bus_clk.common.hw, | ||
1315 | + [CLK_TWSI2_BUS] = &twsi2_bus_clk.common.hw, | ||
1316 | + [CLK_TWSI4_BUS] = &twsi4_bus_clk.common.hw, | ||
1317 | + [CLK_TWSI5_BUS] = &twsi5_bus_clk.common.hw, | ||
1318 | + [CLK_TWSI6_BUS] = &twsi6_bus_clk.common.hw, | ||
1319 | + [CLK_TWSI7_BUS] = &twsi7_bus_clk.common.hw, | ||
1320 | + [CLK_TIMERS1_BUS] = &timers1_bus_clk.common.hw, | ||
1321 | + [CLK_TIMERS2_BUS] = &timers2_bus_clk.common.hw, | ||
1322 | + [CLK_AIB_BUS] = &aib_bus_clk.common.hw, | ||
1323 | + [CLK_ONEWIRE_BUS] = &onewire_bus_clk.common.hw, | ||
1324 | + [CLK_SSPA0_BUS] = &sspa0_bus_clk.common.hw, | ||
1325 | + [CLK_SSPA1_BUS] = &sspa1_bus_clk.common.hw, | ||
1326 | + [CLK_TSEN_BUS] = &tsen_bus_clk.common.hw, | ||
1327 | + [CLK_IPC_AP2AUD_BUS] = &ipc_ap2aud_bus_clk.common.hw, | ||
1328 | +}; | ||
1329 | + | ||
1330 | +static const struct spacemit_ccu_data k1_ccu_apbc_data = { | ||
1331 | + .hws = k1_ccu_apbc_hws, | ||
1332 | + .num = ARRAY_SIZE(k1_ccu_apbc_hws), | ||
1333 | +}; | ||
1334 | + | ||
1335 | +static struct clk_hw *k1_ccu_apmu_hws[] = { | ||
1336 | + [CLK_CCI550] = &cci550_clk.common.hw, | ||
1337 | + [CLK_CPU_C0_HI] = &cpu_c0_hi_clk.common.hw, | ||
1338 | + [CLK_CPU_C0_CORE] = &cpu_c0_core_clk.common.hw, | ||
1339 | + [CLK_CPU_C0_ACE] = &cpu_c0_ace_clk.common.hw, | ||
1340 | + [CLK_CPU_C0_TCM] = &cpu_c0_tcm_clk.common.hw, | ||
1341 | + [CLK_CPU_C1_HI] = &cpu_c1_hi_clk.common.hw, | ||
1342 | + [CLK_CPU_C1_CORE] = &cpu_c1_core_clk.common.hw, | ||
1343 | + [CLK_CPU_C1_ACE] = &cpu_c1_ace_clk.common.hw, | ||
1344 | + [CLK_CCIC_4X] = &ccic_4x_clk.common.hw, | ||
1345 | + [CLK_CCIC1PHY] = &ccic1phy_clk.common.hw, | ||
1346 | + [CLK_SDH_AXI] = &sdh_axi_aclk.common.hw, | ||
1347 | + [CLK_SDH0] = &sdh0_clk.common.hw, | ||
1348 | + [CLK_SDH1] = &sdh1_clk.common.hw, | ||
1349 | + [CLK_SDH2] = &sdh2_clk.common.hw, | ||
1350 | + [CLK_USB_P1] = &usb_p1_aclk.common.hw, | ||
1351 | + [CLK_USB_AXI] = &usb_axi_clk.common.hw, | ||
1352 | + [CLK_USB30] = &usb30_clk.common.hw, | ||
1353 | + [CLK_QSPI] = &qspi_clk.common.hw, | ||
1354 | + [CLK_QSPI_BUS] = &qspi_bus_clk.common.hw, | ||
1355 | + [CLK_DMA] = &dma_clk.common.hw, | ||
1356 | + [CLK_AES] = &aes_clk.common.hw, | ||
1357 | + [CLK_VPU] = &vpu_clk.common.hw, | ||
1358 | + [CLK_GPU] = &gpu_clk.common.hw, | ||
1359 | + [CLK_EMMC] = &emmc_clk.common.hw, | ||
1360 | + [CLK_EMMC_X] = &emmc_x_clk.common.hw, | ||
1361 | + [CLK_AUDIO] = &audio_clk.common.hw, | ||
1362 | + [CLK_HDMI] = &hdmi_mclk.common.hw, | ||
1363 | + [CLK_PMUA_ACLK] = &pmua_aclk.common.hw, | ||
1364 | + [CLK_PCIE0_MASTER] = &pcie0_master_clk.common.hw, | ||
1365 | + [CLK_PCIE0_SLAVE] = &pcie0_slave_clk.common.hw, | ||
1366 | + [CLK_PCIE0_DBI] = &pcie0_dbi_clk.common.hw, | ||
1367 | + [CLK_PCIE1_MASTER] = &pcie1_master_clk.common.hw, | ||
1368 | + [CLK_PCIE1_SLAVE] = &pcie1_slave_clk.common.hw, | ||
1369 | + [CLK_PCIE1_DBI] = &pcie1_dbi_clk.common.hw, | ||
1370 | + [CLK_PCIE2_MASTER] = &pcie2_master_clk.common.hw, | ||
1371 | + [CLK_PCIE2_SLAVE] = &pcie2_slave_clk.common.hw, | ||
1372 | + [CLK_PCIE2_DBI] = &pcie2_dbi_clk.common.hw, | ||
1373 | + [CLK_EMAC0_BUS] = &emac0_bus_clk.common.hw, | ||
1374 | + [CLK_EMAC0_PTP] = &emac0_ptp_clk.common.hw, | ||
1375 | + [CLK_EMAC1_BUS] = &emac1_bus_clk.common.hw, | ||
1376 | + [CLK_EMAC1_PTP] = &emac1_ptp_clk.common.hw, | ||
1377 | + [CLK_JPG] = &jpg_clk.common.hw, | ||
1378 | + [CLK_CCIC2PHY] = &ccic2phy_clk.common.hw, | ||
1379 | + [CLK_CCIC3PHY] = &ccic3phy_clk.common.hw, | ||
1380 | + [CLK_CSI] = &csi_clk.common.hw, | ||
1381 | + [CLK_CAMM0] = &camm0_clk.common.hw, | ||
1382 | + [CLK_CAMM1] = &camm1_clk.common.hw, | ||
1383 | + [CLK_CAMM2] = &camm2_clk.common.hw, | ||
1384 | + [CLK_ISP_CPP] = &isp_cpp_clk.common.hw, | ||
1385 | + [CLK_ISP_BUS] = &isp_bus_clk.common.hw, | ||
1386 | + [CLK_ISP] = &isp_clk.common.hw, | ||
1387 | + [CLK_DPU_MCLK] = &dpu_mclk.common.hw, | ||
1388 | + [CLK_DPU_ESC] = &dpu_esc_clk.common.hw, | ||
1389 | + [CLK_DPU_BIT] = &dpu_bit_clk.common.hw, | ||
1390 | + [CLK_DPU_PXCLK] = &dpu_pxclk.common.hw, | ||
1391 | + [CLK_DPU_HCLK] = &dpu_hclk.common.hw, | ||
1392 | + [CLK_DPU_SPI] = &dpu_spi_clk.common.hw, | ||
1393 | + [CLK_DPU_SPI_HBUS] = &dpu_spi_hbus_clk.common.hw, | ||
1394 | + [CLK_DPU_SPIBUS] = &dpu_spi_bus_clk.common.hw, | ||
1395 | + [CLK_DPU_SPI_ACLK] = &dpu_spi_aclk.common.hw, | ||
1396 | + [CLK_V2D] = &v2d_clk.common.hw, | ||
1397 | + [CLK_EMMC_BUS] = &emmc_bus_clk.common.hw, | ||
1398 | +}; | ||
1399 | + | ||
1400 | +static const struct spacemit_ccu_data k1_ccu_apmu_data = { | ||
1401 | + .hws = k1_ccu_apmu_hws, | ||
1402 | + .num = ARRAY_SIZE(k1_ccu_apmu_hws), | ||
1719 | +}; | 1403 | +}; |
1720 | + | 1404 | + |
1721 | +static int spacemit_ccu_register(struct device *dev, | 1405 | +static int spacemit_ccu_register(struct device *dev, |
1722 | + struct spacemit_ccu_priv *priv) | 1406 | + struct regmap *regmap, struct regmap *lock_regmap, |
1723 | +{ | 1407 | + const struct spacemit_ccu_data *data) |
1724 | + const struct spacemit_ccu_data *data = priv->data; | 1408 | +{ |
1409 | + struct clk_hw_onecell_data *clk_data; | ||
1725 | + int i, ret; | 1410 | + int i, ret; |
1726 | + | 1411 | + |
1727 | + for (i = 0; i < data->hw_clks->num; i++) { | 1412 | + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num), |
1728 | + struct clk_hw *hw = data->hw_clks->hws[i]; | 1413 | + GFP_KERNEL); |
1414 | + if (!clk_data) | ||
1415 | + return -ENOMEM; | ||
1416 | + | ||
1417 | + for (i = 0; i < data->num; i++) { | ||
1418 | + struct clk_hw *hw = data->hws[i]; | ||
1729 | + struct ccu_common *common; | 1419 | + struct ccu_common *common; |
1730 | + const char *name; | 1420 | + const char *name; |
1731 | + | 1421 | + |
1732 | + if (!hw) | 1422 | + if (!hw) { |
1423 | + clk_data->hws[i] = ERR_PTR(-ENOENT); | ||
1733 | + continue; | 1424 | + continue; |
1425 | + } | ||
1426 | + | ||
1427 | + name = hw->init->name; | ||
1734 | + | 1428 | + |
1735 | + common = hw_to_ccu_common(hw); | 1429 | + common = hw_to_ccu_common(hw); |
1736 | + name = hw->init->name; | 1430 | + common->regmap = regmap; |
1737 | + | 1431 | + common->lock_regmap = lock_regmap; |
1738 | + common->base = priv->base; | ||
1739 | + common->lock_base = priv->lock_base; | ||
1740 | + | 1432 | + |
1741 | + ret = devm_clk_hw_register(dev, hw); | 1433 | + ret = devm_clk_hw_register(dev, hw); |
1742 | + if (ret) { | 1434 | + if (ret) { |
1743 | + dev_err(dev, "Cannot register clock %d - %s\n", | 1435 | + dev_err(dev, "Cannot register clock %d - %s\n", |
1744 | + i, name); | 1436 | + i, name); |
1745 | + return ret; | 1437 | + return ret; |
1746 | + } | 1438 | + } |
1439 | + | ||
1440 | + clk_data->hws[i] = hw; | ||
1747 | + } | 1441 | + } |
1748 | + | 1442 | + |
1749 | + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, | 1443 | + clk_data->num = data->num; |
1750 | + data->hw_clks); | 1444 | + |
1445 | + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); | ||
1446 | + if (ret) | ||
1447 | + dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); | ||
1448 | + | ||
1449 | + return ret; | ||
1751 | +} | 1450 | +} |
1752 | + | 1451 | + |
1753 | +static int k1_ccu_probe(struct platform_device *pdev) | 1452 | +static int k1_ccu_probe(struct platform_device *pdev) |
1754 | +{ | 1453 | +{ |
1755 | + const struct spacemit_ccu_data *data; | 1454 | + struct regmap *base_regmap, *lock_regmap = NULL; |
1756 | + struct regmap *base_map, *lock_map = NULL; | ||
1757 | + struct device *dev = &pdev->dev; | 1455 | + struct device *dev = &pdev->dev; |
1758 | + struct spacemit_ccu_priv *priv; | ||
1759 | + struct device_node *parent; | ||
1760 | + int ret; | 1456 | + int ret; |
1761 | + | 1457 | + |
1762 | + data = of_device_get_match_data(dev); | 1458 | + base_regmap = device_node_to_regmap(dev->of_node); |
1763 | + if (WARN_ON(!data)) | 1459 | + if (IS_ERR(base_regmap)) |
1764 | + return -EINVAL; | 1460 | + return dev_err_probe(dev, PTR_ERR(base_regmap), |
1765 | + | ||
1766 | + parent = of_get_parent(dev->of_node); | ||
1767 | + base_map = syscon_node_to_regmap(parent); | ||
1768 | + of_node_put(parent); | ||
1769 | + | ||
1770 | + if (IS_ERR(base_map)) | ||
1771 | + return dev_err_probe(dev, PTR_ERR(base_map), | ||
1772 | + "failed to get regmap\n"); | 1461 | + "failed to get regmap\n"); |
1773 | + | 1462 | + |
1774 | + if (data->need_pll_lock) { | 1463 | + /* |
1775 | + lock_map = syscon_regmap_lookup_by_phandle(dev->of_node, | 1464 | + * The lock status of PLLs locate in MPMU region, while PLLs themselves |
1776 | + "spacemit,mpmu"); | 1465 | + * are in APBS region. Reference to MPMU syscon is required to check PLL |
1777 | + if (IS_ERR(lock_map)) | 1466 | + * status. |
1778 | + return dev_err_probe(dev, PTR_ERR(lock_map), | 1467 | + */ |
1468 | + if (of_device_is_compatible(dev->of_node, "spacemit,k1-pll")) { | ||
1469 | + struct device_node *mpmu = of_parse_phandle(dev->of_node, | ||
1470 | + "spacemit,mpmu", 0); | ||
1471 | + if (!mpmu) | ||
1472 | + return dev_err_probe(dev, -ENODEV, | ||
1473 | + "Cannot parse MPMU region\n"); | ||
1474 | + | ||
1475 | + lock_regmap = device_node_to_regmap(mpmu); | ||
1476 | + of_node_put(mpmu); | ||
1477 | + | ||
1478 | + if (IS_ERR(lock_regmap)) | ||
1479 | + return dev_err_probe(dev, PTR_ERR(lock_regmap), | ||
1779 | + "failed to get lock regmap\n"); | 1480 | + "failed to get lock regmap\n"); |
1780 | + } | 1481 | + } |
1781 | + | 1482 | + |
1782 | + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 1483 | + ret = spacemit_ccu_register(dev, base_regmap, lock_regmap, |
1783 | + if (!priv) | 1484 | + of_device_get_match_data(dev)); |
1784 | + return -ENOMEM; | ||
1785 | + | ||
1786 | + priv->data = data; | ||
1787 | + priv->base = base_map; | ||
1788 | + priv->lock_base = lock_map; | ||
1789 | + | ||
1790 | + ret = spacemit_ccu_register(dev, priv); | ||
1791 | + if (ret) | 1485 | + if (ret) |
1792 | + return dev_err_probe(dev, ret, "failed to register clocks\n"); | 1486 | + return dev_err_probe(dev, ret, "failed to register clocks\n"); |
1793 | + | 1487 | + |
1794 | + return 0; | 1488 | + return 0; |
1795 | +} | 1489 | +} |
1796 | + | 1490 | + |
1797 | +static const struct spacemit_ccu_data k1_ccu_apbs_data = { | ||
1798 | + .need_pll_lock = true, | ||
1799 | + .hw_clks = &k1_ccu_apbs_clks, | ||
1800 | +}; | ||
1801 | + | ||
1802 | +static const struct spacemit_ccu_data k1_ccu_mpmu_data = { | ||
1803 | + .need_pll_lock = false, | ||
1804 | + .hw_clks = &k1_ccu_mpmu_clks, | ||
1805 | +}; | ||
1806 | + | ||
1807 | +static const struct spacemit_ccu_data k1_ccu_apbc_data = { | ||
1808 | + .need_pll_lock = false, | ||
1809 | + .hw_clks = &k1_ccu_apbc_clks, | ||
1810 | +}; | ||
1811 | + | ||
1812 | +static const struct spacemit_ccu_data k1_ccu_apmu_data = { | ||
1813 | + .need_pll_lock = false, | ||
1814 | + .hw_clks = &k1_ccu_apmu_clks, | ||
1815 | +}; | ||
1816 | + | ||
1817 | +static const struct of_device_id of_k1_ccu_match[] = { | 1491 | +static const struct of_device_id of_k1_ccu_match[] = { |
1818 | + { | 1492 | + { |
1819 | + .compatible = "spacemit,k1-ccu-apbs", | 1493 | + .compatible = "spacemit,k1-pll", |
1820 | + .data = &k1_ccu_apbs_data, | 1494 | + .data = &k1_ccu_pll_data, |
1821 | + }, | 1495 | + }, |
1822 | + { | 1496 | + { |
1823 | + .compatible = "spacemit,k1-ccu-mpmu", | 1497 | + .compatible = "spacemit,k1-syscon-mpmu", |
1824 | + .data = &k1_ccu_mpmu_data, | 1498 | + .data = &k1_ccu_mpmu_data, |
1825 | + }, | 1499 | + }, |
1826 | + { | 1500 | + { |
1827 | + .compatible = "spacemit,k1-ccu-apbc", | 1501 | + .compatible = "spacemit,k1-syscon-apbc", |
1828 | + .data = &k1_ccu_apbc_data, | 1502 | + .data = &k1_ccu_apbc_data, |
1829 | + }, | 1503 | + }, |
1830 | + { | 1504 | + { |
1831 | + .compatible = "spacemit,k1-ccu-apmu", | 1505 | + .compatible = "spacemit,k1-syscon-apmu", |
1832 | + .data = &k1_ccu_apmu_data, | 1506 | + .data = &k1_ccu_apmu_data, |
1833 | + }, | 1507 | + }, |
1834 | + { } | 1508 | + { } |
1835 | +}; | 1509 | +}; |
1836 | +MODULE_DEVICE_TABLE(of, of_k1_ccu_match); | 1510 | +MODULE_DEVICE_TABLE(of, of_k1_ccu_match); |
... | ... | ||
1842 | + }, | 1516 | + }, |
1843 | + .probe = k1_ccu_probe, | 1517 | + .probe = k1_ccu_probe, |
1844 | +}; | 1518 | +}; |
1845 | +module_platform_driver(k1_ccu_driver); | 1519 | +module_platform_driver(k1_ccu_driver); |
1846 | + | 1520 | + |
1847 | +MODULE_DESCRIPTION("Spacemit K1 CCU driver"); | 1521 | +MODULE_DESCRIPTION("SpacemiT K1 CCU driver"); |
1848 | +MODULE_AUTHOR("Haylen Chu <heylenay@4d2.org>"); | 1522 | +MODULE_AUTHOR("Haylen Chu <heylenay@4d2.org>"); |
1849 | +MODULE_LICENSE("GPL"); | 1523 | +MODULE_LICENSE("GPL"); |
1850 | diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_common.h | 1524 | diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_common.h |
1851 | new file mode 100644 | 1525 | new file mode 100644 |
1852 | index XXXXXXX..XXXXXXX | 1526 | index XXXXXXX..XXXXXXX |
... | ... | ||
1863 | +#define _CCU_COMMON_H_ | 1537 | +#define _CCU_COMMON_H_ |
1864 | + | 1538 | + |
1865 | +#include <linux/regmap.h> | 1539 | +#include <linux/regmap.h> |
1866 | + | 1540 | + |
1867 | +struct ccu_common { | 1541 | +struct ccu_common { |
1868 | + struct regmap *base; | 1542 | + struct regmap *regmap; |
1869 | + struct regmap *lock_base; | 1543 | + struct regmap *lock_regmap; |
1870 | + | 1544 | + |
1871 | + union { | 1545 | + union { |
1546 | + /* For DDN and MIX */ | ||
1872 | + struct { | 1547 | + struct { |
1873 | + u32 reg_ctrl; | 1548 | + u32 reg_ctrl; |
1874 | + u32 reg_sel; | ||
1875 | + u32 reg_fc; | 1549 | + u32 reg_fc; |
1876 | + u32 fc; | 1550 | + u32 mask_fc; |
1877 | + }; | 1551 | + }; |
1552 | + | ||
1553 | + /* For PLL */ | ||
1878 | + struct { | 1554 | + struct { |
1879 | + u32 reg_swcr1; | 1555 | + u32 reg_swcr1; |
1880 | + u32 reg_swcr2; | ||
1881 | + u32 reg_swcr3; | 1556 | + u32 reg_swcr3; |
1882 | + }; | 1557 | + }; |
1883 | + }; | 1558 | + }; |
1884 | + | 1559 | + |
1885 | + unsigned long flags; | ||
1886 | + const char *name; | ||
1887 | + const char * const *parent_names; | ||
1888 | + int num_parents; | ||
1889 | + | ||
1890 | + struct clk_hw hw; | 1560 | + struct clk_hw hw; |
1891 | +}; | 1561 | +}; |
1892 | + | 1562 | + |
1893 | +static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) | 1563 | +static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) |
1894 | +{ | 1564 | +{ |
1895 | + return container_of(hw, struct ccu_common, hw); | 1565 | + return container_of(hw, struct ccu_common, hw); |
1896 | +} | 1566 | +} |
1897 | + | 1567 | + |
1898 | +#define ccu_read(reg, c, val) regmap_read((c)->base, (c)->reg_##reg, val) | 1568 | +#define ccu_read(c, reg) \ |
1899 | +#define ccu_write(reg, c, val) regmap_write((c)->base, (c)->reg_##reg, val) | 1569 | + ({ \ |
1900 | +#define ccu_update(reg, c, mask, val) \ | 1570 | + u32 tmp; \ |
1901 | + regmap_update_bits((c)->base, (c)->reg_##reg, mask, val) | 1571 | + regmap_read((c)->regmap, (c)->reg_##reg, &tmp); \ |
1902 | +#define ccu_poll(reg, c, tmp, cond, sleep, timeout) \ | 1572 | + tmp; \ |
1903 | + regmap_read_poll_timeout_atomic((c)->base, (c)->reg_##reg, \ | 1573 | + }) |
1904 | + tmp, cond, sleep, timeout) | 1574 | +#define ccu_update(c, reg, mask, val) \ |
1575 | + regmap_update_bits((c)->regmap, (c)->reg_##reg, mask, val) | ||
1905 | + | 1576 | + |
1906 | +#endif /* _CCU_COMMON_H_ */ | 1577 | +#endif /* _CCU_COMMON_H_ */ |
1907 | diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c | 1578 | diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c |
1908 | new file mode 100644 | 1579 | new file mode 100644 |
1909 | index XXXXXXX..XXXXXXX | 1580 | index XXXXXXX..XXXXXXX |
1910 | --- /dev/null | 1581 | --- /dev/null |
1911 | +++ b/drivers/clk/spacemit/ccu_ddn.c | 1582 | +++ b/drivers/clk/spacemit/ccu_ddn.c |
1912 | @@ -XXX,XX +XXX,XX @@ | 1583 | @@ -XXX,XX +XXX,XX @@ |
1913 | +// SPDX-License-Identifier: GPL-2.0-only | 1584 | +// SPDX-License-Identifier: GPL-2.0-only |
1914 | +/* | 1585 | +/* |
1915 | + * Spacemit clock type ddn | ||
1916 | + * | ||
1917 | + * Copyright (c) 2024 SpacemiT Technology Co. Ltd | 1586 | + * Copyright (c) 2024 SpacemiT Technology Co. Ltd |
1918 | + * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org> | 1587 | + * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org> |
1588 | + * | ||
1589 | + * DDN stands for "Divider Denominator Numerator", it's M/N clock with a | ||
1590 | + * constant x2 factor. This clock hardware follows the equation below, | ||
1591 | + * | ||
1592 | + * numerator Fin | ||
1593 | + * 2 * ------------- = ------- | ||
1594 | + * denominator Fout | ||
1595 | + * | ||
1596 | + * Thus, Fout could be calculated with, | ||
1597 | + * | ||
1598 | + * Fin denominator | ||
1599 | + * Fout = ----- * ------------- | ||
1600 | + * 2 numerator | ||
1919 | + */ | 1601 | + */ |
1920 | + | 1602 | + |
1921 | +#include <linux/clk-provider.h> | 1603 | +#include <linux/clk-provider.h> |
1604 | +#include <linux/rational.h> | ||
1922 | + | 1605 | + |
1923 | +#include "ccu_ddn.h" | 1606 | +#include "ccu_ddn.h" |
1924 | + | 1607 | + |
1925 | +/* | 1608 | +static unsigned long ccu_ddn_calc_rate(unsigned long prate, |
1926 | + * It is M/N clock | 1609 | + unsigned long num, unsigned long den) |
1927 | + * | 1610 | +{ |
1928 | + * Fout from synthesizer can be given from two equations: | 1611 | + return prate * den / 2 / num; |
1929 | + * numerator/denominator = Fin / (Fout * factor) | 1612 | +} |
1930 | + */ | 1613 | + |
1931 | +static void ccu_ddn_disable(struct clk_hw *hw) | 1614 | +static unsigned long ccu_ddn_calc_best_rate(struct ccu_ddn *ddn, |
1615 | + unsigned long rate, unsigned long prate, | ||
1616 | + unsigned long *num, unsigned long *den) | ||
1617 | +{ | ||
1618 | + rational_best_approximation(rate, prate / 2, | ||
1619 | + ddn->den_mask >> ddn->den_shift, | ||
1620 | + ddn->num_mask >> ddn->num_shift, | ||
1621 | + den, num); | ||
1622 | + return ccu_ddn_calc_rate(prate, *num, *den); | ||
1623 | +} | ||
1624 | + | ||
1625 | +static long ccu_ddn_round_rate(struct clk_hw *hw, unsigned long rate, | ||
1626 | + unsigned long *prate) | ||
1932 | +{ | 1627 | +{ |
1933 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); | 1628 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); |
1934 | + struct ccu_common *common = &ddn->common; | 1629 | + unsigned long num, den; |
1935 | + | 1630 | + |
1936 | + ccu_update(sel, common, ddn->gate, 0); | 1631 | + return ccu_ddn_calc_best_rate(ddn, rate, *prate, &num, &den); |
1937 | +} | 1632 | +} |
1938 | + | 1633 | + |
1939 | +static int ccu_ddn_enable(struct clk_hw *hw) | 1634 | +static unsigned long ccu_ddn_recalc_rate(struct clk_hw *hw, unsigned long prate) |
1940 | +{ | 1635 | +{ |
1941 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); | 1636 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); |
1942 | + struct ccu_common *common = &ddn->common; | 1637 | + unsigned int val, num, den; |
1943 | + | 1638 | + |
1944 | + ccu_update(sel, common, ddn->gate, ddn->gate); | 1639 | + val = ccu_read(&ddn->common, ctrl); |
1640 | + | ||
1641 | + num = (val & ddn->num_mask) >> ddn->num_shift; | ||
1642 | + den = (val & ddn->den_mask) >> ddn->den_shift; | ||
1643 | + | ||
1644 | + return ccu_ddn_calc_rate(prate, num, den); | ||
1645 | +} | ||
1646 | + | ||
1647 | +static int ccu_ddn_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1648 | + unsigned long prate) | ||
1649 | +{ | ||
1650 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); | ||
1651 | + unsigned long num, den; | ||
1652 | + | ||
1653 | + ccu_ddn_calc_best_rate(ddn, rate, prate, &num, &den); | ||
1654 | + | ||
1655 | + ccu_update(&ddn->common, ctrl, | ||
1656 | + ddn->num_mask | ddn->den_mask, | ||
1657 | + (num << ddn->num_shift) | (den << ddn->den_shift)); | ||
1945 | + | 1658 | + |
1946 | + return 0; | 1659 | + return 0; |
1947 | +} | 1660 | +} |
1948 | + | 1661 | + |
1949 | +static int ccu_ddn_is_enabled(struct clk_hw *hw) | ||
1950 | +{ | ||
1951 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); | ||
1952 | + struct ccu_common *common = &ddn->common; | ||
1953 | + u32 tmp; | ||
1954 | + | ||
1955 | + ccu_read(sel, common, &tmp); | ||
1956 | + | ||
1957 | + return tmp & ddn->gate; | ||
1958 | +} | ||
1959 | + | ||
1960 | +static long clk_ddn_round_rate(struct clk_hw *hw, unsigned long drate, | ||
1961 | + unsigned long *prate) | ||
1962 | +{ | ||
1963 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); | ||
1964 | + struct ccu_ddn_config *params = &ddn->ddn; | ||
1965 | + unsigned long rate = 0, prev_rate; | ||
1966 | + unsigned long result; | ||
1967 | + int i; | ||
1968 | + | ||
1969 | + for (i = 0; i < params->tbl_size; i++) { | ||
1970 | + prev_rate = rate; | ||
1971 | + rate = (*prate * params->tbl[i].den) / | ||
1972 | + (params->tbl[i].num * params->info->factor); | ||
1973 | + if (rate > drate) | ||
1974 | + break; | ||
1975 | + } | ||
1976 | + | ||
1977 | + if ((i == 0) || (i == params->tbl_size)) { | ||
1978 | + result = rate; | ||
1979 | + } else { | ||
1980 | + if ((drate - prev_rate) > (rate - drate)) | ||
1981 | + result = rate; | ||
1982 | + else | ||
1983 | + result = prev_rate; | ||
1984 | + } | ||
1985 | + | ||
1986 | + return result; | ||
1987 | +} | ||
1988 | + | ||
1989 | +static unsigned long clk_ddn_recalc_rate(struct clk_hw *hw, | ||
1990 | + unsigned long parent_rate) | ||
1991 | +{ | ||
1992 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); | ||
1993 | + struct ccu_ddn_config *params = &ddn->ddn; | ||
1994 | + unsigned int val, num, den; | ||
1995 | + unsigned long rate; | ||
1996 | + | ||
1997 | + ccu_read(ctrl, &ddn->common, &val); | ||
1998 | + | ||
1999 | + num = (val >> params->info->num_shift) & params->info->num_mask; | ||
2000 | + den = (val >> params->info->den_shift) & params->info->den_mask; | ||
2001 | + | ||
2002 | + if (!den) | ||
2003 | + return 0; | ||
2004 | + | ||
2005 | + rate = (parent_rate * den) / (num * params->info->factor); | ||
2006 | + | ||
2007 | + return rate; | ||
2008 | +} | ||
2009 | + | ||
2010 | +/* Configures new clock rate*/ | ||
2011 | +static int clk_ddn_set_rate(struct clk_hw *hw, unsigned long drate, | ||
2012 | + unsigned long prate) | ||
2013 | +{ | ||
2014 | + struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); | ||
2015 | + struct ccu_ddn_config *params = &ddn->ddn; | ||
2016 | + struct ccu_ddn_info *info = params->info; | ||
2017 | + unsigned long rate = 0; | ||
2018 | + int i; | ||
2019 | + | ||
2020 | + for (i = 0; i < params->tbl_size; i++) { | ||
2021 | + rate = (prate * params->tbl[i].den) / | ||
2022 | + (params->tbl[i].num * info->factor); | ||
2023 | + | ||
2024 | + if (rate > drate) | ||
2025 | + break; | ||
2026 | + } | ||
2027 | + | ||
2028 | + if (i > 0) | ||
2029 | + i--; | ||
2030 | + | ||
2031 | + ccu_update(ctrl, &ddn->common, | ||
2032 | + info->num_mask | info->den_mask, | ||
2033 | + (params->tbl[i].num << info->num_shift) | | ||
2034 | + (params->tbl[i].den << info->den_shift)); | ||
2035 | + | ||
2036 | + return 0; | ||
2037 | +} | ||
2038 | + | ||
2039 | +const struct clk_ops spacemit_ccu_ddn_ops = { | 1662 | +const struct clk_ops spacemit_ccu_ddn_ops = { |
2040 | + .recalc_rate = clk_ddn_recalc_rate, | 1663 | + .recalc_rate = ccu_ddn_recalc_rate, |
2041 | + .round_rate = clk_ddn_round_rate, | 1664 | + .round_rate = ccu_ddn_round_rate, |
2042 | + .set_rate = clk_ddn_set_rate, | 1665 | + .set_rate = ccu_ddn_set_rate, |
2043 | +}; | ||
2044 | + | ||
2045 | +const struct clk_ops spacemit_ccu_ddn_gate_ops = { | ||
2046 | + .disable = ccu_ddn_disable, | ||
2047 | + .enable = ccu_ddn_enable, | ||
2048 | + .is_enabled = ccu_ddn_is_enabled, | ||
2049 | + .recalc_rate = clk_ddn_recalc_rate, | ||
2050 | + .round_rate = clk_ddn_round_rate, | ||
2051 | + .set_rate = clk_ddn_set_rate, | ||
2052 | +}; | 1666 | +}; |
2053 | diff --git a/drivers/clk/spacemit/ccu_ddn.h b/drivers/clk/spacemit/ccu_ddn.h | 1667 | diff --git a/drivers/clk/spacemit/ccu_ddn.h b/drivers/clk/spacemit/ccu_ddn.h |
2054 | new file mode 100644 | 1668 | new file mode 100644 |
2055 | index XXXXXXX..XXXXXXX | 1669 | index XXXXXXX..XXXXXXX |
2056 | --- /dev/null | 1670 | --- /dev/null |
... | ... | ||
2063 | + */ | 1677 | + */ |
2064 | + | 1678 | + |
2065 | +#ifndef _CCU_DDN_H_ | 1679 | +#ifndef _CCU_DDN_H_ |
2066 | +#define _CCU_DDN_H_ | 1680 | +#define _CCU_DDN_H_ |
2067 | + | 1681 | + |
1682 | +#include <linux/bitops.h> | ||
2068 | +#include <linux/clk-provider.h> | 1683 | +#include <linux/clk-provider.h> |
2069 | + | 1684 | + |
2070 | +#include "ccu_common.h" | 1685 | +#include "ccu_common.h" |
2071 | + | 1686 | + |
2072 | +struct ccu_ddn_tbl { | 1687 | +struct ccu_ddn { |
2073 | + unsigned int num; | 1688 | + struct ccu_common common; |
2074 | + unsigned int den; | ||
2075 | +}; | ||
2076 | + | ||
2077 | +struct ccu_ddn_info { | ||
2078 | + unsigned int factor; | ||
2079 | + unsigned int num_mask; | 1689 | + unsigned int num_mask; |
1690 | + unsigned int num_shift; | ||
2080 | + unsigned int den_mask; | 1691 | + unsigned int den_mask; |
2081 | + unsigned int num_shift; | ||
2082 | + unsigned int den_shift; | 1692 | + unsigned int den_shift; |
2083 | +}; | 1693 | +}; |
2084 | + | 1694 | + |
2085 | +struct ccu_ddn_config { | 1695 | +#define CCU_DDN_INIT(_name, _parent, _flags) \ |
2086 | + struct ccu_ddn_info *info; | 1696 | + CLK_HW_INIT_HW(#_name, &_parent.common.hw, &spacemit_ccu_ddn_ops, _flags) |
2087 | + struct ccu_ddn_tbl *tbl; | 1697 | + |
2088 | + u32 tbl_size; | 1698 | +#define CCU_DDN_DEFINE(_name, _parent, _reg_ctrl, _num_mask, _den_mask, _flags) \ |
2089 | +}; | 1699 | +static struct ccu_ddn _name = { \ |
2090 | + | 1700 | + .common = { \ |
2091 | +struct ccu_ddn { | 1701 | + .reg_ctrl = _reg_ctrl, \ |
2092 | + struct ccu_ddn_config ddn; | 1702 | + .hw.init = CCU_DDN_INIT(_name, _parent, _flags), \ |
2093 | + struct ccu_common common; | 1703 | + }, \ |
2094 | + u32 gate; | 1704 | + .num_mask = _num_mask, \ |
2095 | +}; | 1705 | + .num_shift = __ffs(_num_mask), \ |
2096 | + | 1706 | + .den_mask = _den_mask, \ |
2097 | +#define CCU_DDN_CONFIG(_info, _table) \ | 1707 | + .den_shift = __ffs(_den_mask), \ |
2098 | + { \ | 1708 | +} |
2099 | + .info = (struct ccu_ddn_info *)_info, \ | ||
2100 | + .tbl = (struct ccu_ddn_tbl *)&_table, \ | ||
2101 | + .tbl_size = ARRAY_SIZE(_table), \ | ||
2102 | + } | ||
2103 | + | ||
2104 | +#define CCU_DDN_INIT(_name, _parent, _ops, _flags) \ | ||
2105 | + CLK_HW_INIT_HW(_name, &_parent.common.hw, &_ops, _flags) | ||
2106 | + | ||
2107 | +#define CCU_DDN_DEFINE(_struct, _name, _parent, _info, _table, \ | ||
2108 | + _reg_ctrl, _flags) \ | ||
2109 | + struct ccu_ddn _struct = { \ | ||
2110 | + .ddn = CCU_DDN_CONFIG(_info, _table), \ | ||
2111 | + .common = { \ | ||
2112 | + .reg_ctrl = _reg_ctrl, \ | ||
2113 | + .hw.init = CCU_DDN_INIT(_name, _parent, \ | ||
2114 | + spacemit_ccu_ddn_ops, \ | ||
2115 | + _flags), \ | ||
2116 | + } \ | ||
2117 | + } | ||
2118 | + | ||
2119 | +#define CCU_DDN_GATE_DEFINE(_struct, _name, _parent, _info, _table, \ | ||
2120 | + _reg_ddn, _reg_gate, _gate_mask, _flags) \ | ||
2121 | + struct ccu_ddn _struct = { \ | ||
2122 | + .ddn = CCU_DDN_CONFIG(_info, _table), \ | ||
2123 | + .common = { \ | ||
2124 | + .reg_ctrl = _reg_ddn, \ | ||
2125 | + .reg_sel = _reg_gate, \ | ||
2126 | + .hw.init = CCU_DDN_INIT(_name, _parent, \ | ||
2127 | + &spacemit_ccu_ddn_gate_ops, \ | ||
2128 | + _flags), \ | ||
2129 | + } \ | ||
2130 | + .gate = _gate_mask, \ | ||
2131 | + } | ||
2132 | + | 1709 | + |
2133 | +static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw) | 1710 | +static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw) |
2134 | +{ | 1711 | +{ |
2135 | + struct ccu_common *common = hw_to_ccu_common(hw); | 1712 | + struct ccu_common *common = hw_to_ccu_common(hw); |
2136 | + | 1713 | + |
2137 | + return container_of(common, struct ccu_ddn, common); | 1714 | + return container_of(common, struct ccu_ddn, common); |
2138 | +} | 1715 | +} |
2139 | + | 1716 | + |
2140 | +extern const struct clk_ops spacemit_ccu_ddn_ops, spacemit_ccu_ddn_gate_ops; | 1717 | +extern const struct clk_ops spacemit_ccu_ddn_ops; |
2141 | + | 1718 | + |
2142 | +#endif | 1719 | +#endif |
2143 | diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c | 1720 | diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c |
2144 | new file mode 100644 | 1721 | new file mode 100644 |
2145 | index XXXXXXX..XXXXXXX | 1722 | index XXXXXXX..XXXXXXX |
2146 | --- /dev/null | 1723 | --- /dev/null |
2147 | +++ b/drivers/clk/spacemit/ccu_mix.c | 1724 | +++ b/drivers/clk/spacemit/ccu_mix.c |
2148 | @@ -XXX,XX +XXX,XX @@ | 1725 | @@ -XXX,XX +XXX,XX @@ |
2149 | +// SPDX-License-Identifier: GPL-2.0-only | 1726 | +// SPDX-License-Identifier: GPL-2.0-only |
2150 | +/* | 1727 | +/* |
2151 | + * Spacemit clock type mix(div/mux/gate/factor) | ||
2152 | + * | ||
2153 | + * Copyright (c) 2024 SpacemiT Technology Co. Ltd | 1728 | + * Copyright (c) 2024 SpacemiT Technology Co. Ltd |
2154 | + * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org> | 1729 | + * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org> |
1730 | + * | ||
1731 | + * MIX clock type is the combination of mux, factor or divider, and gate | ||
2155 | + */ | 1732 | + */ |
2156 | + | 1733 | + |
2157 | +#include <linux/clk-provider.h> | 1734 | +#include <linux/clk-provider.h> |
2158 | + | 1735 | + |
2159 | +#include "ccu_mix.h" | 1736 | +#include "ccu_mix.h" |
2160 | + | 1737 | + |
2161 | +#define MIX_TIMEOUT 10000 | 1738 | +#define MIX_FC_TIMEOUT_US 10000 |
1739 | +#define MIX_FC_DELAY_US 5 | ||
2162 | + | 1740 | + |
2163 | +static void ccu_gate_disable(struct clk_hw *hw) | 1741 | +static void ccu_gate_disable(struct clk_hw *hw) |
2164 | +{ | 1742 | +{ |
2165 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1743 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2166 | + struct ccu_common *common = &mix->common; | 1744 | + |
2167 | + struct ccu_gate_config *gate = mix->gate; | 1745 | + ccu_update(&mix->common, ctrl, mix->gate.mask, 0); |
2168 | + | ||
2169 | + ccu_update(ctrl, common, gate->gate_mask, gate->val_disable); | ||
2170 | +} | 1746 | +} |
2171 | + | 1747 | + |
2172 | +static int ccu_gate_enable(struct clk_hw *hw) | 1748 | +static int ccu_gate_enable(struct clk_hw *hw) |
2173 | +{ | 1749 | +{ |
2174 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1750 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2175 | + struct ccu_common *common = &mix->common; | 1751 | + struct ccu_gate_config *gate = &mix->gate; |
2176 | + struct ccu_gate_config *gate = mix->gate; | 1752 | + |
2177 | + u32 val_enable, mask; | 1753 | + ccu_update(&mix->common, ctrl, gate->mask, gate->mask); |
2178 | + u32 tmp; | 1754 | + |
2179 | + | 1755 | + return 0; |
2180 | + val_enable = gate->val_enable; | ||
2181 | + mask = gate->gate_mask; | ||
2182 | + | ||
2183 | + ccu_update(ctrl, common, mask, val_enable); | ||
2184 | + | ||
2185 | + return ccu_poll(ctrl, common, tmp, (tmp & mask) == val_enable, | ||
2186 | + 10, MIX_TIMEOUT); | ||
2187 | +} | 1756 | +} |
2188 | + | 1757 | + |
2189 | +static int ccu_gate_is_enabled(struct clk_hw *hw) | 1758 | +static int ccu_gate_is_enabled(struct clk_hw *hw) |
2190 | +{ | 1759 | +{ |
2191 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1760 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2192 | + struct ccu_common *common = &mix->common; | 1761 | + struct ccu_gate_config *gate = &mix->gate; |
2193 | + struct ccu_gate_config *gate = mix->gate; | 1762 | + |
2194 | + u32 tmp; | 1763 | + return (ccu_read(&mix->common, ctrl) & gate->mask) == gate->mask; |
2195 | + | ||
2196 | + ccu_read(ctrl, common, &tmp); | ||
2197 | + | ||
2198 | + return (tmp & gate->gate_mask) == gate->val_enable; | ||
2199 | +} | 1764 | +} |
2200 | + | 1765 | + |
2201 | +static unsigned long ccu_factor_recalc_rate(struct clk_hw *hw, | 1766 | +static unsigned long ccu_factor_recalc_rate(struct clk_hw *hw, |
2202 | + unsigned long parent_rate) | 1767 | + unsigned long parent_rate) |
2203 | +{ | 1768 | +{ |
2204 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1769 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2205 | + | 1770 | + |
2206 | + return parent_rate * mix->factor->mul / mix->factor->div; | 1771 | + return parent_rate * mix->factor.mul / mix->factor.div; |
2207 | +} | 1772 | +} |
2208 | + | 1773 | + |
2209 | +static unsigned long ccu_div_recalc_rate(struct clk_hw *hw, | 1774 | +static unsigned long ccu_div_recalc_rate(struct clk_hw *hw, |
2210 | + unsigned long parent_rate) | 1775 | + unsigned long parent_rate) |
2211 | +{ | 1776 | +{ |
2212 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1777 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2213 | + struct ccu_common *common = &mix->common; | 1778 | + struct ccu_div_config *div = &mix->div; |
2214 | + struct ccu_div_config *div = mix->div; | ||
2215 | + unsigned long val; | 1779 | + unsigned long val; |
2216 | + u32 reg; | 1780 | + |
2217 | + | 1781 | + val = ccu_read(&mix->common, ctrl) >> div->shift; |
2218 | + ccu_read(ctrl, common, ®); | ||
2219 | + | ||
2220 | + val = reg >> div->shift; | ||
2221 | + val &= (1 << div->width) - 1; | 1782 | + val &= (1 << div->width) - 1; |
2222 | + | 1783 | + |
2223 | + val = divider_recalc_rate(hw, parent_rate, val, div->table, | 1784 | + return divider_recalc_rate(hw, parent_rate, val, NULL, 0, div->width); |
2224 | + div->flags, div->width); | 1785 | +} |
2225 | + | 1786 | + |
2226 | + return val; | 1787 | +/* |
2227 | +} | 1788 | + * Some clocks require a "FC" (frequency change) bit to be set after changing |
2228 | + | 1789 | + * their rates or reparenting. This bit will be automatically cleared by |
1790 | + * hardware in MIX_FC_TIMEOUT_US, which indicates the operation is completed. | ||
1791 | + */ | ||
2229 | +static int ccu_mix_trigger_fc(struct clk_hw *hw) | 1792 | +static int ccu_mix_trigger_fc(struct clk_hw *hw) |
2230 | +{ | 1793 | +{ |
2231 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1794 | + struct ccu_common *common = hw_to_ccu_common(hw); |
2232 | + struct ccu_common *common = &mix->common; | 1795 | + unsigned int val; |
2233 | + unsigned int val = 0; | 1796 | + |
2234 | + | 1797 | + if (common->reg_fc) |
2235 | + ccu_update(fc, common, common->fc, common->fc); | 1798 | + return 0; |
2236 | + | 1799 | + |
2237 | + return ccu_poll(fc, common, val, !(val & common->fc), | 1800 | + ccu_update(common, fc, common->mask_fc, common->mask_fc); |
2238 | + 5, MIX_TIMEOUT); | 1801 | + |
1802 | + return regmap_read_poll_timeout_atomic(common->regmap, common->reg_fc, | ||
1803 | + val, !(val & common->mask_fc), | ||
1804 | + MIX_FC_DELAY_US, | ||
1805 | + MIX_FC_TIMEOUT_US); | ||
2239 | +} | 1806 | +} |
2240 | + | 1807 | + |
2241 | +static long ccu_factor_round_rate(struct clk_hw *hw, unsigned long rate, | 1808 | +static long ccu_factor_round_rate(struct clk_hw *hw, unsigned long rate, |
2242 | + unsigned long *prate) | 1809 | + unsigned long *prate) |
2243 | +{ | 1810 | +{ |
... | ... | ||
2255 | + struct clk_hw **best_parent, | 1822 | + struct clk_hw **best_parent, |
2256 | + unsigned long *best_parent_rate, | 1823 | + unsigned long *best_parent_rate, |
2257 | + u32 *div_val) | 1824 | + u32 *div_val) |
2258 | +{ | 1825 | +{ |
2259 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1826 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2260 | + struct ccu_common *common = &mix->common; | 1827 | + unsigned int parent_num = clk_hw_get_num_parents(hw); |
2261 | + struct ccu_div_config *div = mix->div; | 1828 | + struct ccu_div_config *div = &mix->div; |
2262 | + u32 div_max = div ? 1 << div->width : 1; | 1829 | + u32 div_max = 1 << div->width; |
2263 | + unsigned long best_rate = 0; | 1830 | + unsigned long best_rate = 0; |
2264 | + | 1831 | + |
2265 | + for (int i = 0; i < common->num_parents; i++) { | 1832 | + for (int i = 0; i < parent_num; i++) { |
2266 | + struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i); | 1833 | + struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i); |
1834 | + unsigned long parent_rate; | ||
2267 | + | 1835 | + |
2268 | + if (!parent) | 1836 | + if (!parent) |
2269 | + continue; | 1837 | + continue; |
2270 | + | 1838 | + |
2271 | + unsigned long parent_rate = clk_hw_get_rate(parent); | 1839 | + parent_rate = clk_hw_get_rate(parent); |
2272 | + | 1840 | + |
2273 | + for (int j = 1; j <= div_max; j++) { | 1841 | + for (int j = 1; j <= div_max; j++) { |
2274 | + unsigned long tmp = DIV_ROUND_UP_ULL(parent_rate, j); | 1842 | + unsigned long tmp = DIV_ROUND_CLOSEST_ULL(parent_rate, j); |
2275 | + | 1843 | + |
2276 | + if (abs(tmp - rate) < abs(best_rate - rate)) { | 1844 | + if (abs(tmp - rate) < abs(best_rate - rate)) { |
2277 | + best_rate = tmp; | 1845 | + best_rate = tmp; |
2278 | + | 1846 | + |
2279 | + if (div_val) | 1847 | + if (div_val) |
... | ... | ||
2303 | +static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate, | 1871 | +static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate, |
2304 | + unsigned long parent_rate) | 1872 | + unsigned long parent_rate) |
2305 | +{ | 1873 | +{ |
2306 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1874 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2307 | + struct ccu_common *common = &mix->common; | 1875 | + struct ccu_common *common = &mix->common; |
2308 | + struct ccu_div_config *div = mix->div; | 1876 | + struct ccu_div_config *div = &mix->div; |
2309 | + int ret = 0, tmp = 0; | 1877 | + u32 current_div, target_div, mask; |
2310 | + u32 current_div, target_div; | ||
2311 | + | 1878 | + |
2312 | + ccu_mix_calc_best_rate(hw, rate, NULL, NULL, &target_div); | 1879 | + ccu_mix_calc_best_rate(hw, rate, NULL, NULL, &target_div); |
2313 | + | 1880 | + |
2314 | + ccu_read(ctrl, common, &tmp); | 1881 | + current_div = ccu_read(common, ctrl) >> div->shift; |
2315 | + | ||
2316 | + current_div = tmp >> div->shift; | ||
2317 | + current_div &= (1 << div->width) - 1; | 1882 | + current_div &= (1 << div->width) - 1; |
2318 | + | 1883 | + |
2319 | + if (current_div == target_div) | 1884 | + if (current_div == target_div) |
2320 | + return 0; | 1885 | + return 0; |
2321 | + | 1886 | + |
2322 | + tmp = GENMASK(div->width + div->shift - 1, div->shift); | 1887 | + mask = GENMASK(div->width + div->shift - 1, div->shift); |
2323 | + | 1888 | + |
2324 | + ccu_update(ctrl, common, tmp, target_div << div->shift); | 1889 | + ccu_update(common, ctrl, mask, target_div << div->shift); |
2325 | + | 1890 | + |
2326 | + if (common->reg_fc) | 1891 | + return ccu_mix_trigger_fc(hw); |
2327 | + ret = ccu_mix_trigger_fc(hw); | ||
2328 | + | ||
2329 | + return ret; | ||
2330 | +} | 1892 | +} |
2331 | + | 1893 | + |
2332 | +static u8 ccu_mux_get_parent(struct clk_hw *hw) | 1894 | +static u8 ccu_mux_get_parent(struct clk_hw *hw) |
2333 | +{ | 1895 | +{ |
2334 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1896 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2335 | + struct ccu_common *common = &mix->common; | 1897 | + struct ccu_mux_config *mux = &mix->mux; |
2336 | + struct ccu_mux_config *mux = mix->mux; | ||
2337 | + u32 reg; | ||
2338 | + u8 parent; | 1898 | + u8 parent; |
2339 | + | 1899 | + |
2340 | + ccu_read(ctrl, common, ®); | 1900 | + parent = ccu_read(&mix->common, ctrl) >> mux->shift; |
2341 | + | ||
2342 | + parent = reg >> mux->shift; | ||
2343 | + parent &= (1 << mux->width) - 1; | 1901 | + parent &= (1 << mux->width) - 1; |
2344 | + | 1902 | + |
2345 | + if (mux->table) { | ||
2346 | + int num_parents = clk_hw_get_num_parents(&common->hw); | ||
2347 | + int i; | ||
2348 | + | ||
2349 | + for (i = 0; i < num_parents; i++) | ||
2350 | + if (mux->table[i] == parent) | ||
2351 | + return i; | ||
2352 | + } | ||
2353 | + | ||
2354 | + return parent; | 1903 | + return parent; |
2355 | +} | 1904 | +} |
2356 | + | 1905 | + |
2357 | +static int ccu_mux_set_parent(struct clk_hw *hw, u8 index) | 1906 | +static int ccu_mux_set_parent(struct clk_hw *hw, u8 index) |
2358 | +{ | 1907 | +{ |
2359 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); | 1908 | + struct ccu_mix *mix = hw_to_ccu_mix(hw); |
2360 | + struct ccu_common *common = &mix->common; | 1909 | + struct ccu_mux_config *mux = &mix->mux; |
2361 | + struct ccu_mux_config *mux = mix->mux; | ||
2362 | + int ret = 0; | ||
2363 | + u32 mask; | 1910 | + u32 mask; |
2364 | + | 1911 | + |
2365 | + if (mux->table) | ||
2366 | + index = mux->table[index]; | ||
2367 | + | ||
2368 | + mask = GENMASK(mux->width + mux->shift - 1, mux->shift); | 1912 | + mask = GENMASK(mux->width + mux->shift - 1, mux->shift); |
2369 | + | 1913 | + |
2370 | + ccu_update(ctrl, common, mask, index << mux->shift); | 1914 | + ccu_update(&mix->common, ctrl, mask, index << mux->shift); |
2371 | + | 1915 | + |
2372 | + if (common->reg_fc) | 1916 | + return ccu_mix_trigger_fc(hw); |
2373 | + ret = ccu_mix_trigger_fc(hw); | ||
2374 | + | ||
2375 | + return ret; | ||
2376 | +} | 1917 | +} |
2377 | + | 1918 | + |
2378 | +const struct clk_ops spacemit_ccu_gate_ops = { | 1919 | +const struct clk_ops spacemit_ccu_gate_ops = { |
2379 | + .disable = ccu_gate_disable, | 1920 | + .disable = ccu_gate_disable, |
2380 | + .enable = ccu_gate_enable, | 1921 | + .enable = ccu_gate_enable, |
... | ... | ||
2397 | + .determine_rate = ccu_mix_determine_rate, | 1938 | + .determine_rate = ccu_mix_determine_rate, |
2398 | + .recalc_rate = ccu_div_recalc_rate, | 1939 | + .recalc_rate = ccu_div_recalc_rate, |
2399 | + .set_rate = ccu_mix_set_rate, | 1940 | + .set_rate = ccu_mix_set_rate, |
2400 | +}; | 1941 | +}; |
2401 | + | 1942 | + |
2402 | +const struct clk_ops spacemit_ccu_gate_factor_ops = { | 1943 | +const struct clk_ops spacemit_ccu_factor_gate_ops = { |
2403 | + .disable = ccu_gate_disable, | 1944 | + .disable = ccu_gate_disable, |
2404 | + .enable = ccu_gate_enable, | 1945 | + .enable = ccu_gate_enable, |
2405 | + .is_enabled = ccu_gate_is_enabled, | 1946 | + .is_enabled = ccu_gate_is_enabled, |
2406 | + | 1947 | + |
2407 | + .round_rate = ccu_factor_round_rate, | 1948 | + .round_rate = ccu_factor_round_rate, |
... | ... | ||
2427 | + .determine_rate = ccu_mix_determine_rate, | 1968 | + .determine_rate = ccu_mix_determine_rate, |
2428 | + .recalc_rate = ccu_div_recalc_rate, | 1969 | + .recalc_rate = ccu_div_recalc_rate, |
2429 | + .set_rate = ccu_mix_set_rate, | 1970 | + .set_rate = ccu_mix_set_rate, |
2430 | +}; | 1971 | +}; |
2431 | + | 1972 | + |
2432 | +const struct clk_ops spacemit_ccu_div_mux_gate_ops = { | 1973 | +const struct clk_ops spacemit_ccu_mux_div_gate_ops = { |
2433 | + .disable = ccu_gate_disable, | 1974 | + .disable = ccu_gate_disable, |
2434 | + .enable = ccu_gate_enable, | 1975 | + .enable = ccu_gate_enable, |
2435 | + .is_enabled = ccu_gate_is_enabled, | 1976 | + .is_enabled = ccu_gate_is_enabled, |
2436 | + | 1977 | + |
2437 | + .get_parent = ccu_mux_get_parent, | 1978 | + .get_parent = ccu_mux_get_parent, |
... | ... | ||
2440 | + .determine_rate = ccu_mix_determine_rate, | 1981 | + .determine_rate = ccu_mix_determine_rate, |
2441 | + .recalc_rate = ccu_div_recalc_rate, | 1982 | + .recalc_rate = ccu_div_recalc_rate, |
2442 | + .set_rate = ccu_mix_set_rate, | 1983 | + .set_rate = ccu_mix_set_rate, |
2443 | +}; | 1984 | +}; |
2444 | + | 1985 | + |
2445 | +const struct clk_ops spacemit_ccu_div_mux_ops = { | 1986 | +const struct clk_ops spacemit_ccu_mux_div_ops = { |
2446 | + .get_parent = ccu_mux_get_parent, | 1987 | + .get_parent = ccu_mux_get_parent, |
2447 | + .set_parent = ccu_mux_set_parent, | 1988 | + .set_parent = ccu_mux_set_parent, |
2448 | + | 1989 | + |
2449 | + .determine_rate = ccu_mix_determine_rate, | 1990 | + .determine_rate = ccu_mix_determine_rate, |
2450 | + .recalc_rate = ccu_div_recalc_rate, | 1991 | + .recalc_rate = ccu_div_recalc_rate, |
... | ... | ||
2467 | + | 2008 | + |
2468 | +#include <linux/clk-provider.h> | 2009 | +#include <linux/clk-provider.h> |
2469 | + | 2010 | + |
2470 | +#include "ccu_common.h" | 2011 | +#include "ccu_common.h" |
2471 | + | 2012 | + |
2013 | +/** | ||
2014 | + * struct ccu_gate_config - Gate configuration | ||
2015 | + * | ||
2016 | + * @mask: Mask to enable the gate. Some clocks may have more than one bit | ||
2017 | + * set in this field. | ||
2018 | + */ | ||
2472 | +struct ccu_gate_config { | 2019 | +struct ccu_gate_config { |
2473 | + u32 gate_mask; | 2020 | + u32 mask; |
2474 | + u32 val_enable; | ||
2475 | + u32 val_disable; | ||
2476 | + u32 flags; | ||
2477 | +}; | 2021 | +}; |
2478 | + | 2022 | + |
2479 | +struct ccu_factor_config { | 2023 | +struct ccu_factor_config { |
2480 | + u32 div; | 2024 | + u32 div; |
2481 | + u32 mul; | 2025 | + u32 mul; |
2482 | +}; | 2026 | +}; |
2483 | + | 2027 | + |
2484 | +struct ccu_mux_config { | 2028 | +struct ccu_mux_config { |
2485 | + const u8 *table; | ||
2486 | + u32 flags; | ||
2487 | + u8 shift; | 2029 | + u8 shift; |
2488 | + u8 width; | 2030 | + u8 width; |
2489 | +}; | 2031 | +}; |
2490 | + | 2032 | + |
2491 | +struct ccu_div_config { | 2033 | +struct ccu_div_config { |
2492 | + struct clk_div_table *table; | ||
2493 | + u32 max; | ||
2494 | + u32 offset; | ||
2495 | + u32 flags; | ||
2496 | + u8 shift; | 2034 | + u8 shift; |
2497 | + u8 width; | 2035 | + u8 width; |
2498 | +}; | 2036 | +}; |
2499 | + | 2037 | + |
2500 | +struct ccu_mix { | 2038 | +struct ccu_mix { |
2501 | + struct ccu_factor_config *factor; | 2039 | + struct ccu_factor_config factor; |
2502 | + struct ccu_gate_config *gate; | 2040 | + struct ccu_gate_config gate; |
2503 | + struct ccu_div_config *div; | 2041 | + struct ccu_div_config div; |
2504 | + struct ccu_mux_config *mux; | 2042 | + struct ccu_mux_config mux; |
2505 | + struct ccu_common common; | 2043 | + struct ccu_common common; |
2506 | +}; | 2044 | +}; |
2507 | + | 2045 | + |
2508 | +#define CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, _flags) \ | 2046 | +#define CCU_GATE_INIT(_mask) { .mask = _mask } |
2509 | + (&(struct ccu_gate_config) { \ | 2047 | +#define CCU_FACTOR_INIT(_div, _mul) { .div = _div, .mul = _mul } |
2510 | + .gate_mask = _gate_mask, \ | 2048 | +#define CCU_MUX_INIT(_shift, _width) { .shift = _shift, .width = _width } |
2511 | + .val_enable = _val_enable, \ | 2049 | +#define CCU_DIV_INIT(_shift, _width) { .shift = _shift, .width = _width } |
2512 | + .val_disable = _val_disable, \ | ||
2513 | + .flags = _flags, \ | ||
2514 | + }) | ||
2515 | + | ||
2516 | +#define CCU_FACTOR_INIT(_div, _mul) \ | ||
2517 | + (&(struct ccu_factor_config) { \ | ||
2518 | + .div = _div, \ | ||
2519 | + .mul = _mul, \ | ||
2520 | + }) | ||
2521 | + | ||
2522 | + | ||
2523 | +#define CCU_MUX_INIT(_shift, _width, _table, _flags) \ | ||
2524 | + (&(struct ccu_mux_config) { \ | ||
2525 | + .shift = _shift, \ | ||
2526 | + .width = _width, \ | ||
2527 | + .table = _table, \ | ||
2528 | + .flags = _flags, \ | ||
2529 | + }) | ||
2530 | + | ||
2531 | +#define CCU_DIV_INIT(_shift, _width, _table, _flags) \ | ||
2532 | + (&(struct ccu_div_config) { \ | ||
2533 | + .shift = _shift, \ | ||
2534 | + .width = _width, \ | ||
2535 | + .flags = _flags, \ | ||
2536 | + .table = _table, \ | ||
2537 | + }) | ||
2538 | + | 2050 | + |
2539 | +#define CCU_PARENT_HW(_parent) { .hw = &_parent.common.hw } | 2051 | +#define CCU_PARENT_HW(_parent) { .hw = &_parent.common.hw } |
2540 | +#define CCU_PARENT_NAME(_name) { .fw_name = #_name } | 2052 | +#define CCU_PARENT_NAME(_name) { .fw_name = #_name } |
2541 | + | 2053 | + |
2542 | +#define CCU_MIX_INITHW(_name, _parent, _ops, _flags) \ | 2054 | +#define CCU_MIX_INITHW(_name, _parent, _ops, _flags) \ |
2543 | + (&(struct clk_init_data) { \ | 2055 | + .hw.init = &(struct clk_init_data) { \ |
2544 | + .flags = _flags, \ | 2056 | + .flags = _flags, \ |
2545 | + .name = _name, \ | 2057 | + .name = #_name, \ |
2546 | + .parent_data = (const struct clk_parent_data[]) \ | 2058 | + .parent_data = (const struct clk_parent_data[]) \ |
2547 | + { _parent }, \ | 2059 | + { _parent }, \ |
2548 | + .num_parents = 1, \ | 2060 | + .num_parents = 1, \ |
2549 | + .ops = &_ops, \ | 2061 | + .ops = &_ops, \ |
2550 | + }) | 2062 | + } |
2551 | + | 2063 | + |
2552 | +#define CCU_MIX_INITHW_PARENTS(_name, _parents, _ops, _flags) \ | 2064 | +#define CCU_MIX_INITHW_PARENTS(_name, _parents, _ops, _flags) \ |
2553 | + CLK_HW_INIT_PARENTS_DATA(_name, _parents, \ | 2065 | + .hw.init = CLK_HW_INIT_PARENTS_DATA(#_name, _parents, &_ops, _flags) |
2554 | + &_ops, _flags) | 2066 | + |
2555 | + | 2067 | +#define CCU_GATE_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _flags) \ |
2556 | +#define CCU_GATE_DEFINE(_struct, _name, _parent, _reg, _gate_mask, \ | 2068 | +static struct ccu_mix _name = { \ |
2557 | + _val_enable, _val_disable, _flags) \ | 2069 | + .gate = CCU_GATE_INIT(_mask_gate), \ |
2558 | +struct ccu_mix _struct = { \ | ||
2559 | + .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ | ||
2560 | + _val_disable, 0), \ | ||
2561 | + .common = { \ | 2070 | + .common = { \ |
2562 | + .reg_ctrl = _reg, \ | 2071 | + .reg_ctrl = _reg_ctrl, \ |
2563 | + .name = _name, \ | 2072 | + CCU_MIX_INITHW(_name, _parent, spacemit_ccu_gate_ops, _flags), \ |
2564 | + .num_parents = 1, \ | ||
2565 | + .hw.init = CCU_MIX_INITHW(_name, _parent, \ | ||
2566 | + spacemit_ccu_gate_ops, _flags), \ | ||
2567 | + } \ | 2073 | + } \ |
2568 | +} | 2074 | +} |
2569 | + | 2075 | + |
2570 | +#define CCU_FACTOR_DEFINE(_struct, _name, _parent, _div, _mul) \ | 2076 | +#define CCU_FACTOR_DEFINE(_name, _parent, _div, _mul) \ |
2571 | +struct ccu_mix _struct = { \ | 2077 | +static struct ccu_mix _name = { \ |
2572 | + .factor = CCU_FACTOR_INIT(_div, _mul), \ | 2078 | + .factor = CCU_FACTOR_INIT(_div, _mul), \ |
2573 | + .common = { \ | 2079 | + .common = { \ |
2574 | + .name = _name, \ | 2080 | + CCU_MIX_INITHW(_name, _parent, spacemit_ccu_factor_ops, 0), \ |
2575 | + .num_parents = 1, \ | ||
2576 | + .hw.init = CCU_MIX_INITHW(_name, _parent, \ | ||
2577 | + spacemit_ccu_factor_ops, 0), \ | ||
2578 | + } \ | 2081 | + } \ |
2579 | +} | 2082 | +} |
2580 | + | 2083 | + |
2581 | +#define CCU_MUX_DEFINE(_struct, _name, _parents, _reg, _shift, _width, \ | 2084 | +#define CCU_MUX_DEFINE(_name, _parents, _reg_ctrl, _shift, _width, _flags) \ |
2582 | + _flags) \ | 2085 | +static struct ccu_mix _name = { \ |
2583 | +struct ccu_mix _struct = { \ | 2086 | + .mux = CCU_MUX_INIT(_shift, _width), \ |
2584 | + .mux = CCU_MUX_INIT(_shift, _width, NULL, 0), \ | ||
2585 | + .common = { \ | 2087 | + .common = { \ |
2586 | + .reg_ctrl = _reg, \ | 2088 | + .reg_ctrl = _reg_ctrl, \ |
2587 | + .name = _name, \ | 2089 | + CCU_MIX_INITHW_PARENTS(_name, _parents, spacemit_ccu_mux_ops, \ |
2588 | + .num_parents = ARRAY_SIZE(_parents), \ | 2090 | + _flags), \ |
2589 | + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ | ||
2590 | + spacemit_ccu_mux_ops, _flags),\ | ||
2591 | + } \ | 2091 | + } \ |
2592 | +} | 2092 | +} |
2593 | + | 2093 | + |
2594 | +#define CCU_DIV_DEFINE(_struct, _name, _parent, _reg, _shift, _width, \ | 2094 | +#define CCU_DIV_DEFINE(_name, _parent, _reg_ctrl, _shift, _width, _flags) \ |
2595 | + _flags) \ | 2095 | +static struct ccu_mix _name = { \ |
2596 | +struct ccu_mix _struct = { \ | 2096 | + .div = CCU_DIV_INIT(_shift, _width), \ |
2597 | + .div = CCU_DIV_INIT(_shift, _width, NULL, 0), \ | ||
2598 | + .common = { \ | 2097 | + .common = { \ |
2599 | + .reg_ctrl = _reg, \ | 2098 | + .reg_ctrl = _reg_ctrl, \ |
2600 | + .name = _name, \ | 2099 | + CCU_MIX_INITHW(_name, _parent, spacemit_ccu_div_ops, _flags) \ |
2601 | + .num_parents = 1, \ | ||
2602 | + .hw.init = CCU_MIX_INITHW(_name, _parent, \ | ||
2603 | + spacemit_ccu_div_ops, _flags) \ | ||
2604 | + } \ | 2100 | + } \ |
2605 | +} | 2101 | +} |
2606 | + | 2102 | + |
2607 | +#define CCU_GATE_FACTOR_DEFINE(_struct, _name, _parent, _reg, \ | 2103 | +#define CCU_FACTOR_GATE_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div, \ |
2608 | + _gate_mask, _val_enable, _val_disable, \ | 2104 | + _mul) \ |
2609 | + _div, _mul, _flags) \ | 2105 | +static struct ccu_mix _name = { \ |
2610 | +struct ccu_mix _struct = { \ | 2106 | + .gate = CCU_GATE_INIT(_mask_gate), \ |
2611 | + .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ | ||
2612 | + _val_disable, 0), \ | ||
2613 | + .factor = CCU_FACTOR_INIT(_div, _mul), \ | 2107 | + .factor = CCU_FACTOR_INIT(_div, _mul), \ |
2614 | + .common = { \ | 2108 | + .common = { \ |
2615 | + .reg_ctrl = _reg, \ | 2109 | + .reg_ctrl = _reg_ctrl, \ |
2616 | + .name = _name, \ | 2110 | + CCU_MIX_INITHW(_name, _parent, spacemit_ccu_factor_gate_ops, 0) \ |
2617 | + .num_parents = 1, \ | ||
2618 | + .hw.init = CCU_MIX_INITHW(_name, _parent, \ | ||
2619 | + spacemit_ccu_gate_factor_ops, _flags) \ | ||
2620 | + } \ | 2111 | + } \ |
2621 | +} | 2112 | +} |
2622 | + | 2113 | + |
2623 | +#define CCU_MUX_GATE_DEFINE(_struct, _name, _parents, _reg, _shift, \ | 2114 | +#define CCU_MUX_GATE_DEFINE(_name, _parents, _reg_ctrl, _shift, _width, \ |
2624 | + _width, _gate_mask, _val_enable, \ | 2115 | + _mask_gate, _flags) \ |
2625 | + _val_disable, _flags) \ | 2116 | +static struct ccu_mix _name = { \ |
2626 | +struct ccu_mix _struct = { \ | 2117 | + .gate = CCU_GATE_INIT(_mask_gate), \ |
2627 | + .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ | 2118 | + .mux = CCU_MUX_INIT(_shift, _width), \ |
2628 | + _val_disable, 0), \ | ||
2629 | + .mux = CCU_MUX_INIT(_shift, _width, NULL, 0), \ | ||
2630 | + .common = { \ | 2119 | + .common = { \ |
2631 | + .reg_ctrl = _reg, \ | 2120 | + .reg_ctrl = _reg_ctrl, \ |
2632 | + .name = _name, \ | 2121 | + CCU_MIX_INITHW_PARENTS(_name, _parents, \ |
2633 | + .num_parents = ARRAY_SIZE(_parents), \ | 2122 | + spacemit_ccu_mux_gate_ops, _flags), \ |
2634 | + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ | ||
2635 | + spacemit_ccu_mux_gate_ops, \ | ||
2636 | + _flags), \ | ||
2637 | + } \ | 2123 | + } \ |
2638 | +} | 2124 | +} |
2639 | + | 2125 | + |
2640 | +#define CCU_DIV_GATE_DEFINE(_struct, _name, _parent, _reg, _shift, \ | 2126 | +#define CCU_DIV_GATE_DEFINE(_name, _parent, _reg_ctrl, _shift, _width, \ |
2641 | + _width, _gate_mask, _val_enable, \ | 2127 | + _mask_gate, _flags) \ |
2642 | + _val_disable, _flags) \ | 2128 | +static struct ccu_mix _name = { \ |
2643 | +struct ccu_mix _struct = { \ | 2129 | + .gate = CCU_GATE_INIT(_mask_gate), \ |
2644 | + .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ | 2130 | + .div = CCU_DIV_INIT(_shift, _width), \ |
2645 | + _val_disable, 0), \ | ||
2646 | + .div = CCU_DIV_INIT(_shift, _width, NULL, 0), \ | ||
2647 | + .common = { \ | 2131 | + .common = { \ |
2648 | + .reg_ctrl = _reg, \ | 2132 | + .reg_ctrl = _reg_ctrl, \ |
2649 | + .name = _name, \ | 2133 | + CCU_MIX_INITHW(_name, _parent, spacemit_ccu_div_gate_ops, \ |
2650 | + .num_parents = 1, \ | 2134 | + _flags), \ |
2651 | + .hw.init = CCU_MIX_INITHW(_name, _parent, \ | ||
2652 | + spacemit_ccu_div_gate_ops, _flags), \ | ||
2653 | + } \ | 2135 | + } \ |
2654 | +} | 2136 | +} |
2655 | + | 2137 | + |
2656 | +#define CCU_DIV_MUX_GATE_DEFINE(_struct, _name, _parents, _reg_ctrl, \ | 2138 | +#define CCU_MUX_DIV_GATE_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth, \ |
2657 | + _mshift, _mwidth, _muxshift, _muxwidth, \ | 2139 | + _muxshift, _muxwidth, _mask_gate, _flags) \ |
2658 | + _gate_mask, _val_enable, _val_disable, \ | 2140 | +static struct ccu_mix _name = { \ |
2659 | + _flags) \ | 2141 | + .gate = CCU_GATE_INIT(_mask_gate), \ |
2660 | +struct ccu_mix _struct = { \ | 2142 | + .div = CCU_DIV_INIT(_mshift, _mwidth), \ |
2661 | + .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ | 2143 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ |
2662 | + _val_disable, 0), \ | ||
2663 | + .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ | ||
2664 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ | ||
2665 | + .common = { \ | 2144 | + .common = { \ |
2666 | + .reg_ctrl = _reg_ctrl, \ | 2145 | + .reg_ctrl = _reg_ctrl, \ |
2667 | + .name = _name, \ | 2146 | + CCU_MIX_INITHW_PARENTS(_name, _parents, \ |
2668 | + .num_parents = ARRAY_SIZE(_parents), \ | 2147 | + spacemit_ccu_mux_div_gate_ops, _flags), \ |
2669 | + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ | ||
2670 | + spacemit_ccu_div_mux_gate_ops,\ | ||
2671 | + _flags), \ | ||
2672 | + }, \ | 2148 | + }, \ |
2673 | +} | 2149 | +} |
2674 | + | 2150 | + |
2675 | +#define CCU_DIV2_FC_MUX_GATE_DEFINE(_struct, _name, _parents, \ | 2151 | +#define CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_name, _parents, _reg_ctrl, _reg_fc, \ |
2676 | + _reg_ctrl, _reg_fc, _mshift, \ | 2152 | + _mshift, _mwidth, _mask_fc, _muxshift, \ |
2677 | + _mwidth, _fc, _muxshift, _muxwidth, \ | 2153 | + _muxwidth, _mask_gate, _flags) \ |
2678 | + _gate_mask, _val_enable, \ | 2154 | +static struct ccu_mix _name = { \ |
2679 | + _val_disable, _flags) \ | 2155 | + .gate = CCU_GATE_INIT(_mask_gate), \ |
2680 | +struct ccu_mix _struct = { \ | 2156 | + .div = CCU_DIV_INIT(_mshift, _mwidth), \ |
2681 | + .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ | 2157 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ |
2682 | + _val_disable, 0), \ | ||
2683 | + .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ | ||
2684 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ | ||
2685 | + .common = { \ | 2158 | + .common = { \ |
2686 | + .reg_ctrl = _reg_ctrl, \ | 2159 | + .reg_ctrl = _reg_ctrl, \ |
2687 | + .reg_fc = _reg_fc, \ | 2160 | + .reg_fc = _reg_fc, \ |
2688 | + .fc = _fc, \ | 2161 | + .mask_fc = _mask_fc, \ |
2689 | + .name = _name, \ | 2162 | + CCU_MIX_INITHW_PARENTS(_name, _parents, \ |
2690 | + .num_parents = ARRAY_SIZE(_parents), \ | 2163 | + spacemit_ccu_mux_div_gate_ops, _flags), \ |
2691 | + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ | ||
2692 | + spacemit_ccu_div_mux_gate_ops,\ | ||
2693 | + _flags), \ | ||
2694 | + }, \ | 2164 | + }, \ |
2695 | +} | 2165 | +} |
2696 | + | 2166 | + |
2697 | +#define CCU_DIV_FC_MUX_GATE_DEFINE(_struct, _name, _parents, _reg_ctrl, \ | 2167 | +#define CCU_MUX_DIV_GATE_FC_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth,\ |
2698 | + _mshift, _mwidth, _fc, _muxshift, \ | 2168 | + _mask_fc, _muxshift, _muxwidth, _mask_gate, \ |
2699 | + _muxwidth, _gate_mask, _val_enable, \ | 2169 | + _flags) \ |
2700 | + _val_disable, _flags) \ | 2170 | +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_name, _parents, _reg_ctrl, _reg_ctrl, _mshift,\ |
2701 | +struct ccu_mix _struct = { \ | 2171 | + _mwidth, _mask_fc, _muxshift, _muxwidth, \ |
2702 | + .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ | 2172 | + _mask_gate, _flags) |
2703 | + _val_disable, 0), \ | 2173 | + |
2704 | + .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ | 2174 | +#define CCU_MUX_DIV_FC_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth, \ |
2705 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ | 2175 | + _mask_fc, _muxshift, _muxwidth, _flags) \ |
2176 | +static struct ccu_mix _name = { \ | ||
2177 | + .div = CCU_DIV_INIT(_mshift, _mwidth), \ | ||
2178 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ | ||
2706 | + .common = { \ | 2179 | + .common = { \ |
2707 | + .reg_ctrl = _reg_ctrl, \ | 2180 | + .reg_ctrl = _reg_ctrl, \ |
2708 | + .reg_fc = _reg_ctrl, \ | 2181 | + .reg_fc = _reg_ctrl, \ |
2709 | + .fc = _fc, \ | 2182 | + .mask_fc = _mask_fc, \ |
2710 | + .name = _name, \ | 2183 | + CCU_MIX_INITHW_PARENTS(_name, _parents, \ |
2711 | + .num_parents = ARRAY_SIZE(_parents), \ | 2184 | + spacemit_ccu_mux_div_ops, _flags), \ |
2712 | + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ | ||
2713 | + spacemit_ccu_div_mux_gate_ops,\ | ||
2714 | + _flags), \ | ||
2715 | + }, \ | 2185 | + }, \ |
2716 | +} | 2186 | +} |
2717 | + | 2187 | + |
2718 | +#define CCU_DIV_FC_MUX_DEFINE(_struct, _name, _parents, _reg_ctrl, \ | 2188 | +#define CCU_MUX_FC_DEFINE(_name, _parents, _reg_ctrl, _mask_fc, _muxshift, \ |
2719 | + _mshift, _mwidth, _fc, _muxshift, \ | 2189 | + _muxwidth, _flags) \ |
2720 | + _muxwidth, _flags) \ | 2190 | +static struct ccu_mix _name = { \ |
2721 | +struct ccu_mix _struct = { \ | 2191 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ |
2722 | + .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ | ||
2723 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ | ||
2724 | + .common = { \ | 2192 | + .common = { \ |
2725 | + .reg_ctrl = _reg_ctrl, \ | 2193 | + .reg_ctrl = _reg_ctrl, \ |
2726 | + .reg_fc = _reg_ctrl, \ | 2194 | + .reg_fc = _reg_ctrl, \ |
2727 | + .fc = _fc, \ | 2195 | + .mask_fc = _mask_fc, \ |
2728 | + .name = _name, \ | 2196 | + CCU_MIX_INITHW_PARENTS(_name, _parents, spacemit_ccu_mux_ops, \ |
2729 | + .num_parents = ARRAY_SIZE(_parents), \ | 2197 | + _flags) \ |
2730 | + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ | ||
2731 | + spacemit_ccu_div_mux_ops, \ | ||
2732 | + _flags), \ | ||
2733 | + }, \ | 2198 | + }, \ |
2734 | +} | 2199 | +} |
2735 | + | 2200 | + |
2736 | +#define CCU_MUX_FC_DEFINE(_struct, _name, _parents, _reg_ctrl, _fc, \ | ||
2737 | + _muxshift, _muxwidth, _flags) \ | ||
2738 | +struct ccu_mix _struct = { \ | ||
2739 | + .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ | ||
2740 | + .common = { \ | ||
2741 | + .reg_ctrl = _reg_ctrl, \ | ||
2742 | + .reg_fc = _reg_ctrl, \ | ||
2743 | + .fc = _fc, \ | ||
2744 | + .name = _name, \ | ||
2745 | + .num_parents = ARRAY_SIZE(_parents), \ | ||
2746 | + .hw.init = CCU_MIX_INITHW_PARENTS(_name, _parents, \ | ||
2747 | + spacemit_ccu_mux_ops, _flags) \ | ||
2748 | + }, \ | ||
2749 | +} | ||
2750 | + | ||
2751 | +static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw) | 2201 | +static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw) |
2752 | +{ | 2202 | +{ |
2753 | + struct ccu_common *common = hw_to_ccu_common(hw); | 2203 | + struct ccu_common *common = hw_to_ccu_common(hw); |
2754 | + | 2204 | + |
2755 | + return container_of(common, struct ccu_mix, common); | 2205 | + return container_of(common, struct ccu_mix, common); |
2756 | +} | 2206 | +} |
2757 | + | 2207 | + |
2758 | +extern const struct clk_ops spacemit_ccu_gate_ops, spacemit_ccu_factor_ops; | 2208 | +extern const struct clk_ops spacemit_ccu_gate_ops; |
2759 | +extern const struct clk_ops spacemit_ccu_mux_ops, spacemit_ccu_div_ops; | 2209 | +extern const struct clk_ops spacemit_ccu_factor_ops; |
2760 | + | 2210 | +extern const struct clk_ops spacemit_ccu_mux_ops; |
2761 | +extern const struct clk_ops spacemit_ccu_gate_factor_ops; | 2211 | +extern const struct clk_ops spacemit_ccu_div_ops; |
2212 | +extern const struct clk_ops spacemit_ccu_factor_gate_ops; | ||
2762 | +extern const struct clk_ops spacemit_ccu_div_gate_ops; | 2213 | +extern const struct clk_ops spacemit_ccu_div_gate_ops; |
2763 | +extern const struct clk_ops spacemit_ccu_mux_gate_ops; | 2214 | +extern const struct clk_ops spacemit_ccu_mux_gate_ops; |
2764 | +extern const struct clk_ops spacemit_ccu_div_mux_ops; | 2215 | +extern const struct clk_ops spacemit_ccu_mux_div_ops; |
2765 | + | 2216 | +extern const struct clk_ops spacemit_ccu_mux_div_gate_ops; |
2766 | +extern const struct clk_ops spacemit_ccu_div_mux_gate_ops; | ||
2767 | +#endif /* _CCU_DIV_H_ */ | 2217 | +#endif /* _CCU_DIV_H_ */ |
2768 | diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c | 2218 | diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c |
2769 | new file mode 100644 | 2219 | new file mode 100644 |
2770 | index XXXXXXX..XXXXXXX | 2220 | index XXXXXXX..XXXXXXX |
2771 | --- /dev/null | 2221 | --- /dev/null |
2772 | +++ b/drivers/clk/spacemit/ccu_pll.c | 2222 | +++ b/drivers/clk/spacemit/ccu_pll.c |
2773 | @@ -XXX,XX +XXX,XX @@ | 2223 | @@ -XXX,XX +XXX,XX @@ |
2774 | +// SPDX-License-Identifier: GPL-2.0-only | 2224 | +// SPDX-License-Identifier: GPL-2.0-only |
2775 | +/* | 2225 | +/* |
2776 | + * Spacemit clock type pll | ||
2777 | + * | ||
2778 | + * Copyright (c) 2024 SpacemiT Technology Co. Ltd | 2226 | + * Copyright (c) 2024 SpacemiT Technology Co. Ltd |
2779 | + * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org> | 2227 | + * Copyright (c) 2024 Haylen Chu <heylenay@4d2.org> |
2780 | + */ | 2228 | + */ |
2781 | + | 2229 | + |
2782 | +#include <linux/clk-provider.h> | 2230 | +#include <linux/clk-provider.h> |
2231 | +#include <linux/math.h> | ||
2783 | +#include <linux/regmap.h> | 2232 | +#include <linux/regmap.h> |
2784 | + | 2233 | + |
2785 | +#include "ccu_common.h" | 2234 | +#include "ccu_common.h" |
2786 | +#include "ccu_pll.h" | 2235 | +#include "ccu_pll.h" |
2787 | + | 2236 | + |
2788 | +#define PLL_MIN_FREQ 600000000 | 2237 | +#define PLL_TIMEOUT_US 3000 |
2789 | +#define PLL_MAX_FREQ 3400000000 | 2238 | +#define PLL_DELAY_US 5 |
2790 | +#define PLL_DELAY_TIME 3000 | 2239 | + |
2791 | + | 2240 | +#define PLL_SWCR3_EN ((u32)BIT(31)) |
2792 | +#define PLL_SWCR1_REG5_OFF 0 | 2241 | +#define PLL_SWCR3_MASK GENMASK(30, 0) |
2793 | +#define PLL_SWCR1_REG5_MASK GENMASK(7, 0) | 2242 | + |
2794 | +#define PLL_SWCR1_REG6_OFF 8 | 2243 | +static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_pll *pll, |
2795 | +#define PLL_SWCR1_REG6_MASK GENMASK(15, 8) | 2244 | + unsigned long rate) |
2796 | +#define PLL_SWCR1_REG7_OFF 16 | 2245 | +{ |
2797 | +#define PLL_SWCR1_REG7_MASK GENMASK(23, 16) | 2246 | + struct ccu_pll_config *config = &pll->config; |
2798 | +#define PLL_SWCR1_REG8_OFF 24 | 2247 | + const struct ccu_pll_rate_tbl *best_entry; |
2799 | +#define PLL_SWCR1_REG8_MASK GENMASK(31, 24) | 2248 | + unsigned long best_delta = ULONG_MAX; |
2800 | + | 2249 | + int i; |
2801 | +#define PLL_SWCR2_DIVn_EN(n) BIT(n + 1) | 2250 | + |
2802 | +#define PLL_SWCR2_ATEST_EN BIT(12) | 2251 | + for (i = 0; i < config->tbl_num; i++) { |
2803 | +#define PLL_SWCR2_CKTEST_EN BIT(13) | 2252 | + const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i]; |
2804 | +#define PLL_SWCR2_DTEST_EN BIT(14) | 2253 | + unsigned long delta = abs_diff(entry->rate, rate); |
2805 | + | 2254 | + |
2806 | +#define PLL_SWCR3_DIV_FRC_OFF 0 | 2255 | + if (delta < best_delta) { |
2807 | +#define PLL_SWCR3_DIV_FRC_MASK GENMASK(23, 0) | 2256 | + best_delta = delta; |
2808 | +#define PLL_SWCR3_DIV_INT_OFF 24 | 2257 | + best_entry = entry; |
2809 | +#define PLL_SWCR3_DIV_INT_MASK GENMASK(30, 24) | 2258 | + } |
2810 | +#define PLL_SWCR3_EN BIT(31) | 2259 | + } |
2260 | + | ||
2261 | + return best_entry; | ||
2262 | +} | ||
2263 | + | ||
2264 | +static const struct ccu_pll_rate_tbl *ccu_pll_lookup_matched_entry(struct ccu_pll *pll) | ||
2265 | +{ | ||
2266 | + struct ccu_pll_config *config = &pll->config; | ||
2267 | + u32 swcr1, swcr3; | ||
2268 | + int i; | ||
2269 | + | ||
2270 | + swcr1 = ccu_read(&pll->common, swcr1); | ||
2271 | + swcr3 = ccu_read(&pll->common, swcr3); | ||
2272 | + swcr3 &= PLL_SWCR3_MASK; | ||
2273 | + | ||
2274 | + for (i = 0; i < config->tbl_num; i++) { | ||
2275 | + const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i]; | ||
2276 | + | ||
2277 | + if (swcr1 == entry->swcr1 && swcr3 == entry->swcr3) | ||
2278 | + return entry; | ||
2279 | + } | ||
2280 | + | ||
2281 | + return NULL; | ||
2282 | +} | ||
2283 | + | ||
2284 | +static void ccu_pll_update_param(struct ccu_pll *pll, const struct ccu_pll_rate_tbl *entry) | ||
2285 | +{ | ||
2286 | + struct ccu_common *common = &pll->common; | ||
2287 | + | ||
2288 | + regmap_write(common->regmap, common->reg_swcr1, entry->swcr1); | ||
2289 | + ccu_update(common, swcr3, PLL_SWCR3_MASK, entry->swcr3); | ||
2290 | +} | ||
2811 | + | 2291 | + |
2812 | +static int ccu_pll_is_enabled(struct clk_hw *hw) | 2292 | +static int ccu_pll_is_enabled(struct clk_hw *hw) |
2813 | +{ | 2293 | +{ |
2814 | + struct ccu_pll *p = hw_to_ccu_pll(hw); | 2294 | + struct ccu_common *common = hw_to_ccu_common(hw); |
2815 | + u32 tmp; | 2295 | + |
2816 | + | 2296 | + return ccu_read(common, swcr3) & PLL_SWCR3_EN; |
2817 | + ccu_read(swcr3, &p->common, &tmp); | ||
2818 | + | ||
2819 | + return tmp & PLL_SWCR3_EN; | ||
2820 | +} | ||
2821 | + | ||
2822 | +/* frequency unit Mhz, return pll vco freq */ | ||
2823 | +static unsigned long ccu_pll_get_vco_freq(struct clk_hw *hw) | ||
2824 | +{ | ||
2825 | + unsigned int reg5, reg6, reg7, reg8, size, i; | ||
2826 | + unsigned int div_int, div_frc; | ||
2827 | + struct ccu_pll_rate_tbl *freq_pll_regs_table; | ||
2828 | + struct ccu_pll *p = hw_to_ccu_pll(hw); | ||
2829 | + struct ccu_common *common = &p->common; | ||
2830 | + u32 tmp; | ||
2831 | + | ||
2832 | + ccu_read(swcr1, common, &tmp); | ||
2833 | + reg5 = (tmp & PLL_SWCR1_REG5_MASK) >> PLL_SWCR1_REG5_OFF; | ||
2834 | + reg6 = (tmp & PLL_SWCR1_REG6_MASK) >> PLL_SWCR1_REG6_OFF; | ||
2835 | + reg7 = (tmp & PLL_SWCR1_REG7_MASK) >> PLL_SWCR1_REG7_OFF; | ||
2836 | + reg8 = (tmp & PLL_SWCR1_REG8_MASK) >> PLL_SWCR1_REG8_OFF; | ||
2837 | + | ||
2838 | + ccu_read(swcr3, common, &tmp); | ||
2839 | + div_int = (tmp & PLL_SWCR3_DIV_INT_MASK) >> PLL_SWCR3_DIV_INT_OFF; | ||
2840 | + div_frc = (tmp & PLL_SWCR3_DIV_FRC_MASK) >> PLL_SWCR3_DIV_FRC_OFF; | ||
2841 | + | ||
2842 | + freq_pll_regs_table = p->pll.rate_tbl; | ||
2843 | + size = p->pll.tbl_size; | ||
2844 | + | ||
2845 | + for (i = 0; i < size; i++) | ||
2846 | + if ((freq_pll_regs_table[i].reg5 == reg5) && | ||
2847 | + (freq_pll_regs_table[i].reg6 == reg6) && | ||
2848 | + (freq_pll_regs_table[i].reg7 == reg7) && | ||
2849 | + (freq_pll_regs_table[i].reg8 == reg8) && | ||
2850 | + (freq_pll_regs_table[i].div_int == div_int) && | ||
2851 | + (freq_pll_regs_table[i].div_frac == div_frc)) | ||
2852 | + return freq_pll_regs_table[i].rate; | ||
2853 | + | ||
2854 | + WARN_ON_ONCE(1); | ||
2855 | + | ||
2856 | + return 0; | ||
2857 | +} | 2297 | +} |
2858 | + | 2298 | + |
2859 | +static int ccu_pll_enable(struct clk_hw *hw) | 2299 | +static int ccu_pll_enable(struct clk_hw *hw) |
2860 | +{ | 2300 | +{ |
2861 | + struct ccu_pll *p = hw_to_ccu_pll(hw); | 2301 | + struct ccu_pll *pll = hw_to_ccu_pll(hw); |
2862 | + struct ccu_common *common = &p->common; | 2302 | + struct ccu_common *common = &pll->common; |
2863 | + unsigned int tmp; | 2303 | + unsigned int tmp; |
2864 | + int ret; | 2304 | + |
2865 | + | 2305 | + ccu_update(common, swcr3, PLL_SWCR3_EN, PLL_SWCR3_EN); |
2866 | + if (ccu_pll_is_enabled(hw)) | ||
2867 | + return 0; | ||
2868 | + | ||
2869 | + ccu_update(swcr3, common, PLL_SWCR3_EN, PLL_SWCR3_EN); | ||
2870 | + | 2306 | + |
2871 | + /* check lock status */ | 2307 | + /* check lock status */ |
2872 | + ret = regmap_read_poll_timeout_atomic(common->lock_base, | 2308 | + return regmap_read_poll_timeout_atomic(common->lock_regmap, |
2873 | + p->pll.reg_lock, | 2309 | + pll->config.reg_lock, |
2874 | + tmp, | 2310 | + tmp, |
2875 | + tmp & p->pll.lock_enable_bit, | 2311 | + tmp & pll->config.mask_lock, |
2876 | + 5, PLL_DELAY_TIME); | 2312 | + PLL_DELAY_US, PLL_TIMEOUT_US); |
2877 | + | ||
2878 | + return ret; | ||
2879 | +} | 2313 | +} |
2880 | + | 2314 | + |
2881 | +static void ccu_pll_disable(struct clk_hw *hw) | 2315 | +static void ccu_pll_disable(struct clk_hw *hw) |
2882 | +{ | 2316 | +{ |
2883 | + struct ccu_pll *p = hw_to_ccu_pll(hw); | 2317 | + struct ccu_common *common = hw_to_ccu_common(hw); |
2884 | + struct ccu_common *common = &p->common; | 2318 | + |
2885 | + | 2319 | + ccu_update(common, swcr3, PLL_SWCR3_EN, 0); |
2886 | + ccu_update(swcr3, common, PLL_SWCR3_EN, 0); | ||
2887 | +} | 2320 | +} |
2888 | + | 2321 | + |
2889 | +/* | 2322 | +/* |
2890 | + * pll rate change requires sequence: | 2323 | + * PLLs must be gated before changing rate, which is ensured by |
2891 | + * clock off -> change rate setting -> clock on | 2324 | + * flag CLK_SET_RATE_GATE. |
2892 | + * This function doesn't really change rate, but cache the config | ||
2893 | + */ | 2325 | + */ |
2894 | +static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, | 2326 | +static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, |
2895 | + unsigned long parent_rate) | 2327 | + unsigned long parent_rate) |
2896 | +{ | 2328 | +{ |
2897 | + struct ccu_pll *p = hw_to_ccu_pll(hw); | 2329 | + struct ccu_pll *pll = hw_to_ccu_pll(hw); |
2898 | + struct ccu_common *common = &p->common; | 2330 | + const struct ccu_pll_rate_tbl *entry; |
2899 | + struct ccu_pll_config *params = &p->pll; | 2331 | + |
2900 | + struct ccu_pll_rate_tbl *entry = NULL; | 2332 | + entry = ccu_pll_lookup_best_rate(pll, rate); |
2901 | + u32 mask, val; | 2333 | + ccu_pll_update_param(pll, entry); |
2902 | + int i; | ||
2903 | + | ||
2904 | + for (i = 0; i < params->tbl_size; i++) { | ||
2905 | + if (rate == params->rate_tbl[i].rate) { | ||
2906 | + entry = ¶ms->rate_tbl[i]; | ||
2907 | + break; | ||
2908 | + } | ||
2909 | + } | ||
2910 | + | ||
2911 | + if (WARN_ON_ONCE(!entry)) | ||
2912 | + return -EINVAL; | ||
2913 | + | ||
2914 | + mask = PLL_SWCR1_REG5_MASK | PLL_SWCR1_REG6_MASK; | ||
2915 | + mask |= PLL_SWCR1_REG7_MASK | PLL_SWCR1_REG8_MASK; | ||
2916 | + val = entry->reg5 << PLL_SWCR1_REG5_OFF; | ||
2917 | + val |= entry->reg6 << PLL_SWCR1_REG6_OFF; | ||
2918 | + val |= entry->reg7 << PLL_SWCR1_REG7_OFF; | ||
2919 | + val |= entry->reg8 << PLL_SWCR1_REG8_OFF; | ||
2920 | + ccu_update(swcr1, common, mask, val); | ||
2921 | + | ||
2922 | + mask = PLL_SWCR3_DIV_INT_MASK | PLL_SWCR3_DIV_FRC_MASK; | ||
2923 | + val = entry->div_int << PLL_SWCR3_DIV_INT_OFF; | ||
2924 | + val |= entry->div_frac << PLL_SWCR3_DIV_FRC_OFF; | ||
2925 | + ccu_update(swcr3, common, mask, val); | ||
2926 | + | 2334 | + |
2927 | + return 0; | 2335 | + return 0; |
2928 | +} | 2336 | +} |
2929 | + | 2337 | + |
2930 | +static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, | 2338 | +static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, |
2931 | + unsigned long parent_rate) | 2339 | + unsigned long parent_rate) |
2932 | +{ | 2340 | +{ |
2933 | + return ccu_pll_get_vco_freq(hw); | 2341 | + struct ccu_pll *pll = hw_to_ccu_pll(hw); |
2342 | + const struct ccu_pll_rate_tbl *entry; | ||
2343 | + | ||
2344 | + entry = ccu_pll_lookup_matched_entry(pll); | ||
2345 | + | ||
2346 | + WARN_ON_ONCE(!entry); | ||
2347 | + | ||
2348 | + return entry ? entry->rate : -EINVAL; | ||
2934 | +} | 2349 | +} |
2935 | + | 2350 | + |
2936 | +static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate, | 2351 | +static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate, |
2937 | + unsigned long *prate) | 2352 | + unsigned long *prate) |
2938 | +{ | 2353 | +{ |
2939 | + struct ccu_pll *p = hw_to_ccu_pll(hw); | 2354 | + struct ccu_pll *pll = hw_to_ccu_pll(hw); |
2940 | + struct ccu_pll_config *params = &p->pll; | 2355 | + |
2941 | + unsigned long max_rate = 0; | 2356 | + return ccu_pll_lookup_best_rate(pll, rate)->rate; |
2942 | + unsigned int i; | 2357 | +} |
2943 | + | 2358 | + |
2944 | + for (i = 0; i < params->tbl_size; i++) { | 2359 | +static int ccu_pll_init(struct clk_hw *hw) |
2945 | + if (params->rate_tbl[i].rate <= rate) { | 2360 | +{ |
2946 | + if (max_rate < params->rate_tbl[i].rate) | 2361 | + struct ccu_pll *pll = hw_to_ccu_pll(hw); |
2947 | + max_rate = params->rate_tbl[i].rate; | 2362 | + |
2948 | + } | 2363 | + if (ccu_pll_lookup_matched_entry(pll)) |
2949 | + } | 2364 | + return 0; |
2950 | + | 2365 | + |
2951 | + return MAX(max_rate, PLL_MIN_FREQ); | 2366 | + ccu_pll_disable(hw); |
2367 | + ccu_pll_update_param(pll, &pll->config.rate_tbl[0]); | ||
2368 | + | ||
2369 | + return 0; | ||
2952 | +} | 2370 | +} |
2953 | + | 2371 | + |
2954 | +const struct clk_ops spacemit_ccu_pll_ops = { | 2372 | +const struct clk_ops spacemit_ccu_pll_ops = { |
2373 | + .init = ccu_pll_init, | ||
2955 | + .enable = ccu_pll_enable, | 2374 | + .enable = ccu_pll_enable, |
2956 | + .disable = ccu_pll_disable, | 2375 | + .disable = ccu_pll_disable, |
2957 | + .set_rate = ccu_pll_set_rate, | 2376 | + .set_rate = ccu_pll_set_rate, |
2958 | + .recalc_rate = ccu_pll_recalc_rate, | 2377 | + .recalc_rate = ccu_pll_recalc_rate, |
2959 | + .round_rate = ccu_pll_round_rate, | 2378 | + .round_rate = ccu_pll_round_rate, |
2960 | + .is_enabled = ccu_pll_is_enabled, | 2379 | + .is_enabled = ccu_pll_is_enabled, |
2961 | +}; | 2380 | +}; |
2962 | + | ||
2963 | diff --git a/drivers/clk/spacemit/ccu_pll.h b/drivers/clk/spacemit/ccu_pll.h | 2381 | diff --git a/drivers/clk/spacemit/ccu_pll.h b/drivers/clk/spacemit/ccu_pll.h |
2964 | new file mode 100644 | 2382 | new file mode 100644 |
2965 | index XXXXXXX..XXXXXXX | 2383 | index XXXXXXX..XXXXXXX |
2966 | --- /dev/null | 2384 | --- /dev/null |
2967 | +++ b/drivers/clk/spacemit/ccu_pll.h | 2385 | +++ b/drivers/clk/spacemit/ccu_pll.h |
... | ... | ||
2977 | + | 2395 | + |
2978 | +#include <linux/clk-provider.h> | 2396 | +#include <linux/clk-provider.h> |
2979 | + | 2397 | + |
2980 | +#include "ccu_common.h" | 2398 | +#include "ccu_common.h" |
2981 | + | 2399 | + |
2400 | +/** | ||
2401 | + * struct ccu_pll_rate_tbl - Structure mapping between PLL rate and register | ||
2402 | + * configuration. | ||
2403 | + * | ||
2404 | + * @rate: PLL rate | ||
2405 | + * @swcr1: Register value of PLLX_SW1_CTRL (PLLx_SWCR1). | ||
2406 | + * @swcr3: Register value of the PLLx_SW3_CTRL's lowest 31 bits of | ||
2407 | + * PLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling | ||
2408 | + * the PLL and not contained in this field. | ||
2409 | + */ | ||
2982 | +struct ccu_pll_rate_tbl { | 2410 | +struct ccu_pll_rate_tbl { |
2983 | + unsigned long long rate; | 2411 | + unsigned long rate; |
2984 | + u32 reg5; | 2412 | + u32 swcr1; |
2985 | + u32 reg6; | 2413 | + u32 swcr3; |
2986 | + u32 reg7; | ||
2987 | + u32 reg8; | ||
2988 | + unsigned int div_int; | ||
2989 | + unsigned int div_frac; | ||
2990 | +}; | 2414 | +}; |
2991 | + | 2415 | + |
2992 | +struct ccu_pll_config { | 2416 | +struct ccu_pll_config { |
2993 | + struct ccu_pll_rate_tbl *rate_tbl; | 2417 | + const struct ccu_pll_rate_tbl *rate_tbl; |
2994 | + u32 tbl_size; | 2418 | + u32 tbl_num; |
2995 | + u32 reg_lock; | 2419 | + u32 reg_lock; |
2996 | + u32 lock_enable_bit; | 2420 | + u32 mask_lock; |
2997 | +}; | 2421 | +}; |
2998 | + | 2422 | + |
2999 | +#define CCU_PLL_RATE(_rate, _reg5, _reg6, _reg7, _reg8, _div_int, _div_frac) \ | 2423 | +#define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \ |
3000 | + { \ | 2424 | + { \ |
3001 | + .rate = (_rate), \ | 2425 | + .rate = _rate, \ |
3002 | + .reg5 = (_reg5), \ | 2426 | + .swcr1 = _swcr1, \ |
3003 | + .reg6 = (_reg6), \ | 2427 | + .swcr3 = _swcr3, \ |
3004 | + .reg7 = (_reg7), \ | ||
3005 | + .reg8 = (_reg8), \ | ||
3006 | + .div_int = (_div_int), \ | ||
3007 | + .div_frac = (_div_frac), \ | ||
3008 | + } | 2428 | + } |
3009 | + | 2429 | + |
3010 | +struct ccu_pll { | 2430 | +struct ccu_pll { |
3011 | + struct ccu_pll_config pll; | ||
3012 | + struct ccu_common common; | 2431 | + struct ccu_common common; |
3013 | +}; | 2432 | + struct ccu_pll_config config; |
3014 | + | 2433 | +}; |
3015 | +#define CCU_PLL_CONFIG(_table, _reg_lock, _lock_enable_bit) \ | 2434 | + |
2435 | +#define CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock) \ | ||
3016 | + { \ | 2436 | + { \ |
3017 | + .rate_tbl = (struct ccu_pll_rate_tbl *)&(_table), \ | 2437 | + .rate_tbl = _table, \ |
3018 | + .tbl_size = ARRAY_SIZE(_table), \ | 2438 | + .tbl_num = ARRAY_SIZE(_table), \ |
3019 | + .reg_lock = (_reg_lock), \ | 2439 | + .reg_lock = (_reg_lock), \ |
3020 | + .lock_enable_bit = (_lock_enable_bit), \ | 2440 | + .mask_lock = (_mask_lock), \ |
3021 | + } | 2441 | + } |
3022 | + | 2442 | + |
3023 | +#define CCU_PLL_HWINIT(_name, _flags) \ | 2443 | +#define CCU_PLL_HWINIT(_name, _flags) \ |
3024 | + CLK_HW_INIT_NO_PARENT(_name, &spacemit_ccu_pll_ops, _flags) | 2444 | + (&(struct clk_init_data) { \ |
3025 | + | 2445 | + .name = #_name, \ |
3026 | +#define CCU_PLL_DEFINE(_struct, _name, _table, _reg_swcr1, _reg_swcr2, \ | 2446 | + .ops = &spacemit_ccu_pll_ops, \ |
3027 | + _reg_swcr3, _reg_lock, _lock_enable_bit, _flags) \ | 2447 | + .parent_data = &(struct clk_parent_data) { .index = 0 }, \ |
3028 | + \ | 2448 | + .num_parents = 1, \ |
3029 | + struct ccu_pll _struct = { \ | 2449 | + .flags = _flags, \ |
3030 | + .pll = CCU_PLL_CONFIG(_table, _reg_lock, _lock_enable_bit), \ | 2450 | + }) |
3031 | + .common = { \ | 2451 | + |
3032 | + .reg_swcr1 = _reg_swcr1, \ | 2452 | +#define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, _reg_lock, \ |
3033 | + .reg_swcr2 = _reg_swcr2, \ | 2453 | + _mask_lock, _flags) \ |
3034 | + .reg_swcr3 = _reg_swcr3, \ | 2454 | +static struct ccu_pll _name = { \ |
3035 | + .hw.init = CCU_PLL_HWINIT(_name, _flags) \ | 2455 | + .config = CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock), \ |
3036 | + } \ | 2456 | + .common = { \ |
3037 | + } | 2457 | + .reg_swcr1 = _reg_swcr1, \ |
2458 | + .reg_swcr3 = _reg_swcr3, \ | ||
2459 | + .hw.init = CCU_PLL_HWINIT(_name, _flags) \ | ||
2460 | + } \ | ||
2461 | +} | ||
3038 | + | 2462 | + |
3039 | +static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) | 2463 | +static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) |
3040 | +{ | 2464 | +{ |
3041 | + struct ccu_common *common = hw_to_ccu_common(hw); | 2465 | + struct ccu_common *common = hw_to_ccu_common(hw); |
3042 | + | 2466 | + |
... | ... | ||
3045 | + | 2469 | + |
3046 | +extern const struct clk_ops spacemit_ccu_pll_ops; | 2470 | +extern const struct clk_ops spacemit_ccu_pll_ops; |
3047 | + | 2471 | + |
3048 | +#endif | 2472 | +#endif |
3049 | -- | 2473 | -- |
3050 | 2.47.1 | 2474 | 2.49.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | The control register for TWSI8 clocks, APBC_TWSI8_CLK_RST, contains mux | ||
2 | selection bits, reset assertion bit and enable bits for function and bus | ||
3 | clocks. It has a quirk that reading always results in zero. | ||
1 | 4 | ||
5 | As a workaround, let's hardcode the mux value as zero to select | ||
6 | pll1_d78_31p5 as parent and treat twsi8_clk as a gate, whose enable mask | ||
7 | is combined from the real bus and function clocks to avoid the | ||
8 | write-only register being shared between two clk_hws, in which case | ||
9 | updates of one clk_hw zero the other's bits. | ||
10 | |||
11 | With a 1:1 factor serving as placeholder for the bus clock, the I2C-8 | ||
12 | controller could be brought up, which is essential for boards attaching | ||
13 | power-management chips to it. | ||
14 | |||
15 | Signed-off-by: Haylen Chu <heylenay@4d2.org> | ||
16 | --- | ||
17 | drivers/clk/spacemit/ccu-k1.c | 5 +++++ | ||
18 | 1 file changed, 5 insertions(+) | ||
19 | |||
20 | diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c | ||
21 | index XXXXXXX..XXXXXXX 100644 | ||
22 | --- a/drivers/clk/spacemit/ccu-k1.c | ||
23 | +++ b/drivers/clk/spacemit/ccu-k1.c | ||
24 | @@ -XXX,XX +XXX,XX @@ CCU_MUX_GATE_DEFINE(twsi6_clk, twsi_parents, APBC_TWSI6_CLK_RST, 4, 3, BIT(1), | ||
25 | 0); | ||
26 | CCU_MUX_GATE_DEFINE(twsi7_clk, twsi_parents, APBC_TWSI7_CLK_RST, 4, 3, BIT(1), | ||
27 | 0); | ||
28 | +CCU_GATE_DEFINE(twsi8_clk, CCU_PARENT_HW(pll1_d78_31p5), APBC_TWSI8_CLK_RST, | ||
29 | + BIT(1) | BIT(0), 0); | ||
30 | |||
31 | static const struct clk_parent_data timer_parents[] = { | ||
32 | CCU_PARENT_HW(pll1_d192_12p8), | ||
33 | @@ -XXX,XX +XXX,XX @@ CCU_GATE_DEFINE(twsi6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI6_CLK_RST, | ||
34 | BIT(0), 0); | ||
35 | CCU_GATE_DEFINE(twsi7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI7_CLK_RST, | ||
36 | BIT(0), 0); | ||
37 | +CCU_FACTOR_DEFINE(twsi8_bus_clk, CCU_PARENT_HW(apb_clk), 1, 1); | ||
38 | |||
39 | CCU_GATE_DEFINE(timers1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS1_CLK_RST, | ||
40 | BIT(0), 0); | ||
41 | @@ -XXX,XX +XXX,XX @@ static struct clk_hw *k1_ccu_apbc_hws[] = { | ||
42 | [CLK_TWSI5] = &twsi5_clk.common.hw, | ||
43 | [CLK_TWSI6] = &twsi6_clk.common.hw, | ||
44 | [CLK_TWSI7] = &twsi7_clk.common.hw, | ||
45 | + [CLK_TWSI8] = &twsi8_clk.common.hw, | ||
46 | [CLK_TIMERS1] = &timers1_clk.common.hw, | ||
47 | [CLK_TIMERS2] = &timers2_clk.common.hw, | ||
48 | [CLK_AIB] = &aib_clk.common.hw, | ||
49 | @@ -XXX,XX +XXX,XX @@ static struct clk_hw *k1_ccu_apbc_hws[] = { | ||
50 | [CLK_TWSI5_BUS] = &twsi5_bus_clk.common.hw, | ||
51 | [CLK_TWSI6_BUS] = &twsi6_bus_clk.common.hw, | ||
52 | [CLK_TWSI7_BUS] = &twsi7_bus_clk.common.hw, | ||
53 | + [CLK_TWSI8_BUS] = &twsi8_bus_clk.common.hw, | ||
54 | [CLK_TIMERS1_BUS] = &timers1_bus_clk.common.hw, | ||
55 | [CLK_TIMERS2_BUS] = &timers2_bus_clk.common.hw, | ||
56 | [CLK_AIB_BUS] = &aib_bus_clk.common.hw, | ||
57 | -- | ||
58 | 2.49.0 | diff view generated by jsdifflib |
1 | Add clock controllers for APBC, APBS, APMU and MPMU regions along with | 1 | Describe the PLL and system controllers that're capable of generating |
---|---|---|---|
2 | system controllers which they belong to. | 2 | clock signals in the devicetree. |
3 | 3 | ||
4 | Signed-off-by: Haylen Chu <heylenay@4d2.org> | 4 | Signed-off-by: Haylen Chu <heylenay@4d2.org> |
5 | --- | 5 | --- |
6 | arch/riscv/boot/dts/spacemit/k1.dtsi | 97 ++++++++++++++++++++++++++++ | 6 | arch/riscv/boot/dts/spacemit/k1.dtsi | 75 ++++++++++++++++++++++++++++ |
7 | 1 file changed, 97 insertions(+) | 7 | 1 file changed, 75 insertions(+) |
8 | 8 | ||
9 | diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi | 9 | diff --git a/arch/riscv/boot/dts/spacemit/k1.dtsi b/arch/riscv/boot/dts/spacemit/k1.dtsi |
10 | index XXXXXXX..XXXXXXX 100644 | 10 | index XXXXXXX..XXXXXXX 100644 |
11 | --- a/arch/riscv/boot/dts/spacemit/k1.dtsi | 11 | --- a/arch/riscv/boot/dts/spacemit/k1.dtsi |
12 | +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi | 12 | +++ b/arch/riscv/boot/dts/spacemit/k1.dtsi |
13 | @@ -XXX,XX +XXX,XX @@ | 13 | @@ -XXX,XX +XXX,XX @@ |
14 | * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name> | 14 | * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name> |
15 | */ | 15 | */ |
16 | 16 | ||
17 | +#include <dt-bindings/clock/spacemit,k1-ccu.h> | 17 | +#include <dt-bindings/clock/spacemit,k1-syscon.h> |
18 | + | 18 | + |
19 | /dts-v1/; | 19 | /dts-v1/; |
20 | / { | 20 | / { |
21 | #address-cells = <2>; | 21 | #address-cells = <2>; |
22 | @@ -XXX,XX +XXX,XX @@ cluster1_l2_cache: l2-cache1 { | 22 | @@ -XXX,XX +XXX,XX @@ cluster1_l2_cache: l2-cache1 { |
23 | }; | 23 | }; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | + clocks { | 26 | + clocks { |
27 | + #address-cells = <0x2>; | ||
28 | + #size-cells = <0x2>; | ||
29 | + ranges; | ||
30 | + | ||
31 | + vctcxo_1m: clock-1m { | 27 | + vctcxo_1m: clock-1m { |
32 | + compatible = "fixed-clock"; | 28 | + compatible = "fixed-clock"; |
33 | + clock-frequency = <1000000>; | 29 | + clock-frequency = <1000000>; |
34 | + clock-output-names = "vctcxo_1m"; | 30 | + clock-output-names = "vctcxo_1m"; |
35 | + #clock-cells = <0>; | 31 | + #clock-cells = <0>; |
... | ... | ||
63 | @@ -XXX,XX +XXX,XX @@ soc { | 59 | @@ -XXX,XX +XXX,XX @@ soc { |
64 | dma-noncoherent; | 60 | dma-noncoherent; |
65 | ranges; | 61 | ranges; |
66 | 62 | ||
67 | + syscon_apbc: system-control@d4015000 { | 63 | + syscon_apbc: system-control@d4015000 { |
68 | + compatible = "spacemit,k1-apbc-syscon", "syscon", | 64 | + compatible = "spacemit,k1-syscon-apbc"; |
69 | + "simple-mfd"; | ||
70 | + reg = <0x0 0xd4015000 0x0 0x1000>; | 65 | + reg = <0x0 0xd4015000 0x0 0x1000>; |
71 | + | 66 | + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, |
72 | + clk_apbc: clock-controller { | 67 | + <&vctcxo_24m>; |
73 | + compatible = "spacemit,k1-ccu-apbc"; | 68 | + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", |
74 | + clocks = <&osc_32k>, <&vctcxo_1m>, | 69 | + "vctcxo_24m"; |
75 | + <&vctcxo_3m>, <&vctcxo_24m>; | 70 | + #clock-cells = <1>; |
76 | + clock-names = "osc", "vctcxo_1m", | 71 | + #reset-cells = <1>; |
77 | + "vctcxo_3m", "vctcxo_24m"; | ||
78 | + #clock-cells = <1>; | ||
79 | + }; | ||
80 | + }; | 72 | + }; |
81 | + | 73 | + |
82 | uart0: serial@d4017000 { | 74 | uart0: serial@d4017000 { |
83 | compatible = "spacemit,k1-uart", "intel,xscale-uart"; | 75 | compatible = "spacemit,k1-uart", "intel,xscale-uart"; |
84 | reg = <0x0 0xd4017000 0x0 0x100>; | 76 | reg = <0x0 0xd4017000 0x0 0x100>; |
85 | @@ -XXX,XX +XXX,XX @@ uart9: serial@d4017800 { | 77 | @@ -XXX,XX +XXX,XX @@ pinctrl: pinctrl@d401e000 { |
86 | status = "disabled"; | 78 | reg = <0x0 0xd401e000 0x0 0x400>; |
87 | }; | 79 | }; |
88 | 80 | ||
89 | + syscon_mpmu: system-control@d4050000 { | 81 | + syscon_mpmu: system-controller@d4050000 { |
90 | + compatible = "spacemit,k1-mpmu-syscon", "syscon", | 82 | + compatible = "spacemit,k1-syscon-mpmu"; |
91 | + "simple-mfd"; | ||
92 | + reg = <0x0 0xd4050000 0x0 0x209c>; | 83 | + reg = <0x0 0xd4050000 0x0 0x209c>; |
93 | + | 84 | + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, |
94 | + clk_mpmu: clock-controller { | 85 | + <&vctcxo_24m>; |
95 | + compatible = "spacemit,k1-ccu-mpmu"; | 86 | + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", |
96 | + clocks = <&osc_32k>, <&vctcxo_1m>, | 87 | + "vctcxo_24m"; |
97 | + <&vctcxo_3m>, <&vctcxo_24m>; | 88 | + #clock-cells = <1>; |
98 | + clock-names = "osc", "vctcxo_1m", | 89 | + #power-domain-cells = <1>; |
99 | + "vctcxo_3m", "vctcxo_24m"; | 90 | + #reset-cells = <1>; |
100 | + #clock-cells = <1>; | ||
101 | + }; | ||
102 | + }; | 91 | + }; |
103 | + | 92 | + |
104 | + syscon_apbs: system-control@d4090000 { | 93 | + pll: system-control@d4090000 { |
105 | + compatible = "spacemit,k1-apbs-syscon", "syscon", | 94 | + compatible = "spacemit,k1-pll"; |
106 | + "simple-mfd"; | ||
107 | + reg = <0x0 0xd4090000 0x0 0x1000>; | 95 | + reg = <0x0 0xd4090000 0x0 0x1000>; |
108 | + | 96 | + clocks = <&vctcxo_24m>; |
109 | + clk_apbs: clock-controller { | 97 | + spacemit,mpmu = <&syscon_mpmu>; |
110 | + compatible = "spacemit,k1-ccu-apbs"; | 98 | + #clock-cells = <1>; |
111 | + clocks = <&osc_32k>, <&vctcxo_1m>, | ||
112 | + <&vctcxo_3m>, <&vctcxo_24m>; | ||
113 | + clock-names = "osc", "vctcxo_1m", | ||
114 | + "vctcxo_3m", "vctcxo_24m"; | ||
115 | + spacemit,mpmu = <&syscon_mpmu>; | ||
116 | + #clock-cells = <1>; | ||
117 | + }; | ||
118 | + }; | 99 | + }; |
119 | + | 100 | + |
120 | + syscon_apmu: system-control@d4282800 { | 101 | + syscon_apmu: system-control@d4282800 { |
121 | + compatible = "spacemit,k1-apmu-syscon", "syscon", | 102 | + compatible = "spacemit,k1-syscon-apmu"; |
122 | + "simple-mfd"; | ||
123 | + reg = <0x0 0xd4282800 0x0 0x400>; | 103 | + reg = <0x0 0xd4282800 0x0 0x400>; |
124 | + | 104 | + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, |
125 | + clk_apmu: clock-controller { | 105 | + <&vctcxo_24m>; |
126 | + compatible = "spacemit,k1-ccu-apmu"; | 106 | + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", |
127 | + clocks = <&osc_32k>, <&vctcxo_1m>, | 107 | + "vctcxo_24m"; |
128 | + <&vctcxo_3m>, <&vctcxo_24m>; | 108 | + #clock-cells = <1>; |
129 | + clock-names = "osc", "vctcxo_1m", | 109 | + #power-domain-cells = <1>; |
130 | + "vctcxo_3m", "vctcxo_24m"; | 110 | + #reset-cells = <1>; |
131 | + #clock-cells = <1>; | ||
132 | + }; | ||
133 | + }; | 111 | + }; |
134 | + | 112 | + |
135 | plic: interrupt-controller@e0000000 { | 113 | plic: interrupt-controller@e0000000 { |
136 | compatible = "spacemit,k1-plic", "sifive,plic-1.0.0"; | 114 | compatible = "spacemit,k1-plic", "sifive,plic-1.0.0"; |
137 | reg = <0x0 0xe0000000 0x0 0x4000000>; | 115 | reg = <0x0 0xe0000000 0x0 0x4000000>; |
138 | -- | 116 | -- |
139 | 2.47.1 | 117 | 2.49.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Clock controller unit, or CCU, generates various clocks frequency for | ||
2 | peripherals integrated in SpacemiT K1 SoC and is essential for normal | ||
3 | operation. Let's enable it in defconfig. | ||
1 | 4 | ||
5 | Signed-off-by: Haylen Chu <heylenay@4d2.org> | ||
6 | --- | ||
7 | arch/riscv/configs/defconfig | 2 ++ | ||
8 | 1 file changed, 2 insertions(+) | ||
9 | |||
10 | diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig | ||
11 | index XXXXXXX..XXXXXXX 100644 | ||
12 | --- a/arch/riscv/configs/defconfig | ||
13 | +++ b/arch/riscv/configs/defconfig | ||
14 | @@ -XXX,XX +XXX,XX @@ CONFIG_CLK_SOPHGO_CV1800=y | ||
15 | CONFIG_CLK_SOPHGO_SG2042_PLL=y | ||
16 | CONFIG_CLK_SOPHGO_SG2042_CLKGEN=y | ||
17 | CONFIG_CLK_SOPHGO_SG2042_RPGATE=y | ||
18 | +CONFIG_SPACEMIT_CCU=y | ||
19 | +CONFIG_SPACEMIT_K1_CCU=y | ||
20 | CONFIG_SUN8I_DE2_CCU=m | ||
21 | CONFIG_SUN50I_IOMMU=y | ||
22 | CONFIG_RPMSG_CHAR=y | ||
23 | -- | ||
24 | 2.49.0 | diff view generated by jsdifflib |