diff options
Diffstat (limited to 'drivers/clk/bcm')
-rw-r--r-- | drivers/clk/bcm/Kconfig | 2 | ||||
-rw-r--r-- | drivers/clk/bcm/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-bcm21664.c | 290 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-bcm281xx.c | 231 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-kona-setup.c | 229 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-kona.c | 266 | ||||
-rw-r--r-- | drivers/clk/bcm/clk-kona.h | 160 |
7 files changed, 944 insertions, 235 deletions
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index a7262fb8ce55..75506e53075b 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig | |||
@@ -6,4 +6,4 @@ config CLK_BCM_KONA | |||
6 | help | 6 | help |
7 | Enable common clock framework support for Broadcom SoCs | 7 | Enable common clock framework support for Broadcom SoCs |
8 | using "Kona" style clock control units, including those | 8 | using "Kona" style clock control units, including those |
9 | in the BCM281xx family. | 9 | in the BCM281xx and BCM21664 families. |
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index cf93359aa862..6297d05a9a10 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o | 1 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o |
2 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o | 2 | obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o |
3 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o | 3 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o |
4 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o | ||
diff --git a/drivers/clk/bcm/clk-bcm21664.c b/drivers/clk/bcm/clk-bcm21664.c new file mode 100644 index 000000000000..eeae4cad2281 --- /dev/null +++ b/drivers/clk/bcm/clk-bcm21664.c | |||
@@ -0,0 +1,290 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Broadcom Corporation | ||
3 | * Copyright 2014 Linaro Limited | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation version 2. | ||
8 | * | ||
9 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
10 | * kind, whether express or implied; without even the implied warranty | ||
11 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include "clk-kona.h" | ||
16 | #include "dt-bindings/clock/bcm21664.h" | ||
17 | |||
18 | #define BCM21664_CCU_COMMON(_name, _capname) \ | ||
19 | KONA_CCU_COMMON(BCM21664, _name, _capname) | ||
20 | |||
21 | /* Root CCU */ | ||
22 | |||
23 | static struct peri_clk_data frac_1m_data = { | ||
24 | .gate = HW_SW_GATE(0x214, 16, 0, 1), | ||
25 | .clocks = CLOCKS("ref_crystal"), | ||
26 | }; | ||
27 | |||
28 | static struct ccu_data root_ccu_data = { | ||
29 | BCM21664_CCU_COMMON(root, ROOT), | ||
30 | /* no policy control */ | ||
31 | .kona_clks = { | ||
32 | [BCM21664_ROOT_CCU_FRAC_1M] = | ||
33 | KONA_CLK(root, frac_1m, peri), | ||
34 | [BCM21664_ROOT_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
35 | }, | ||
36 | }; | ||
37 | |||
38 | /* AON CCU */ | ||
39 | |||
40 | static struct peri_clk_data hub_timer_data = { | ||
41 | .gate = HW_SW_GATE(0x0414, 16, 0, 1), | ||
42 | .hyst = HYST(0x0414, 8, 9), | ||
43 | .clocks = CLOCKS("bbl_32k", | ||
44 | "frac_1m", | ||
45 | "dft_19_5m"), | ||
46 | .sel = SELECTOR(0x0a10, 0, 2), | ||
47 | .trig = TRIGGER(0x0a40, 4), | ||
48 | }; | ||
49 | |||
50 | static struct ccu_data aon_ccu_data = { | ||
51 | BCM21664_CCU_COMMON(aon, AON), | ||
52 | .policy = { | ||
53 | .enable = CCU_LVM_EN(0x0034, 0), | ||
54 | .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), | ||
55 | }, | ||
56 | .kona_clks = { | ||
57 | [BCM21664_AON_CCU_HUB_TIMER] = | ||
58 | KONA_CLK(aon, hub_timer, peri), | ||
59 | [BCM21664_AON_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
60 | }, | ||
61 | }; | ||
62 | |||
63 | /* Master CCU */ | ||
64 | |||
65 | static struct peri_clk_data sdio1_data = { | ||
66 | .gate = HW_SW_GATE(0x0358, 18, 2, 3), | ||
67 | .clocks = CLOCKS("ref_crystal", | ||
68 | "var_52m", | ||
69 | "ref_52m", | ||
70 | "var_96m", | ||
71 | "ref_96m"), | ||
72 | .sel = SELECTOR(0x0a28, 0, 3), | ||
73 | .div = DIVIDER(0x0a28, 4, 14), | ||
74 | .trig = TRIGGER(0x0afc, 9), | ||
75 | }; | ||
76 | |||
77 | static struct peri_clk_data sdio2_data = { | ||
78 | .gate = HW_SW_GATE(0x035c, 18, 2, 3), | ||
79 | .clocks = CLOCKS("ref_crystal", | ||
80 | "var_52m", | ||
81 | "ref_52m", | ||
82 | "var_96m", | ||
83 | "ref_96m"), | ||
84 | .sel = SELECTOR(0x0a2c, 0, 3), | ||
85 | .div = DIVIDER(0x0a2c, 4, 14), | ||
86 | .trig = TRIGGER(0x0afc, 10), | ||
87 | }; | ||
88 | |||
89 | static struct peri_clk_data sdio3_data = { | ||
90 | .gate = HW_SW_GATE(0x0364, 18, 2, 3), | ||
91 | .clocks = CLOCKS("ref_crystal", | ||
92 | "var_52m", | ||
93 | "ref_52m", | ||
94 | "var_96m", | ||
95 | "ref_96m"), | ||
96 | .sel = SELECTOR(0x0a34, 0, 3), | ||
97 | .div = DIVIDER(0x0a34, 4, 14), | ||
98 | .trig = TRIGGER(0x0afc, 12), | ||
99 | }; | ||
100 | |||
101 | static struct peri_clk_data sdio4_data = { | ||
102 | .gate = HW_SW_GATE(0x0360, 18, 2, 3), | ||
103 | .clocks = CLOCKS("ref_crystal", | ||
104 | "var_52m", | ||
105 | "ref_52m", | ||
106 | "var_96m", | ||
107 | "ref_96m"), | ||
108 | .sel = SELECTOR(0x0a30, 0, 3), | ||
109 | .div = DIVIDER(0x0a30, 4, 14), | ||
110 | .trig = TRIGGER(0x0afc, 11), | ||
111 | }; | ||
112 | |||
113 | static struct peri_clk_data sdio1_sleep_data = { | ||
114 | .clocks = CLOCKS("ref_32k"), /* Verify */ | ||
115 | .gate = HW_SW_GATE(0x0358, 18, 2, 3), | ||
116 | }; | ||
117 | |||
118 | static struct peri_clk_data sdio2_sleep_data = { | ||
119 | .clocks = CLOCKS("ref_32k"), /* Verify */ | ||
120 | .gate = HW_SW_GATE(0x035c, 18, 2, 3), | ||
121 | }; | ||
122 | |||
123 | static struct peri_clk_data sdio3_sleep_data = { | ||
124 | .clocks = CLOCKS("ref_32k"), /* Verify */ | ||
125 | .gate = HW_SW_GATE(0x0364, 18, 2, 3), | ||
126 | }; | ||
127 | |||
128 | static struct peri_clk_data sdio4_sleep_data = { | ||
129 | .clocks = CLOCKS("ref_32k"), /* Verify */ | ||
130 | .gate = HW_SW_GATE(0x0360, 18, 2, 3), | ||
131 | }; | ||
132 | |||
133 | static struct ccu_data master_ccu_data = { | ||
134 | BCM21664_CCU_COMMON(master, MASTER), | ||
135 | .policy = { | ||
136 | .enable = CCU_LVM_EN(0x0034, 0), | ||
137 | .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), | ||
138 | }, | ||
139 | .kona_clks = { | ||
140 | [BCM21664_MASTER_CCU_SDIO1] = | ||
141 | KONA_CLK(master, sdio1, peri), | ||
142 | [BCM21664_MASTER_CCU_SDIO2] = | ||
143 | KONA_CLK(master, sdio2, peri), | ||
144 | [BCM21664_MASTER_CCU_SDIO3] = | ||
145 | KONA_CLK(master, sdio3, peri), | ||
146 | [BCM21664_MASTER_CCU_SDIO4] = | ||
147 | KONA_CLK(master, sdio4, peri), | ||
148 | [BCM21664_MASTER_CCU_SDIO1_SLEEP] = | ||
149 | KONA_CLK(master, sdio1_sleep, peri), | ||
150 | [BCM21664_MASTER_CCU_SDIO2_SLEEP] = | ||
151 | KONA_CLK(master, sdio2_sleep, peri), | ||
152 | [BCM21664_MASTER_CCU_SDIO3_SLEEP] = | ||
153 | KONA_CLK(master, sdio3_sleep, peri), | ||
154 | [BCM21664_MASTER_CCU_SDIO4_SLEEP] = | ||
155 | KONA_CLK(master, sdio4_sleep, peri), | ||
156 | [BCM21664_MASTER_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
157 | }, | ||
158 | }; | ||
159 | |||
160 | /* Slave CCU */ | ||
161 | |||
162 | static struct peri_clk_data uartb_data = { | ||
163 | .gate = HW_SW_GATE(0x0400, 18, 2, 3), | ||
164 | .clocks = CLOCKS("ref_crystal", | ||
165 | "var_156m", | ||
166 | "ref_156m"), | ||
167 | .sel = SELECTOR(0x0a10, 0, 2), | ||
168 | .div = FRAC_DIVIDER(0x0a10, 4, 12, 8), | ||
169 | .trig = TRIGGER(0x0afc, 2), | ||
170 | }; | ||
171 | |||
172 | static struct peri_clk_data uartb2_data = { | ||
173 | .gate = HW_SW_GATE(0x0404, 18, 2, 3), | ||
174 | .clocks = CLOCKS("ref_crystal", | ||
175 | "var_156m", | ||
176 | "ref_156m"), | ||
177 | .sel = SELECTOR(0x0a14, 0, 2), | ||
178 | .div = FRAC_DIVIDER(0x0a14, 4, 12, 8), | ||
179 | .trig = TRIGGER(0x0afc, 3), | ||
180 | }; | ||
181 | |||
182 | static struct peri_clk_data uartb3_data = { | ||
183 | .gate = HW_SW_GATE(0x0408, 18, 2, 3), | ||
184 | .clocks = CLOCKS("ref_crystal", | ||
185 | "var_156m", | ||
186 | "ref_156m"), | ||
187 | .sel = SELECTOR(0x0a18, 0, 2), | ||
188 | .div = FRAC_DIVIDER(0x0a18, 4, 12, 8), | ||
189 | .trig = TRIGGER(0x0afc, 4), | ||
190 | }; | ||
191 | |||
192 | static struct peri_clk_data bsc1_data = { | ||
193 | .gate = HW_SW_GATE(0x0458, 18, 2, 3), | ||
194 | .clocks = CLOCKS("ref_crystal", | ||
195 | "var_104m", | ||
196 | "ref_104m", | ||
197 | "var_13m", | ||
198 | "ref_13m"), | ||
199 | .sel = SELECTOR(0x0a64, 0, 3), | ||
200 | .trig = TRIGGER(0x0afc, 23), | ||
201 | }; | ||
202 | |||
203 | static struct peri_clk_data bsc2_data = { | ||
204 | .gate = HW_SW_GATE(0x045c, 18, 2, 3), | ||
205 | .clocks = CLOCKS("ref_crystal", | ||
206 | "var_104m", | ||
207 | "ref_104m", | ||
208 | "var_13m", | ||
209 | "ref_13m"), | ||
210 | .sel = SELECTOR(0x0a68, 0, 3), | ||
211 | .trig = TRIGGER(0x0afc, 24), | ||
212 | }; | ||
213 | |||
214 | static struct peri_clk_data bsc3_data = { | ||
215 | .gate = HW_SW_GATE(0x0470, 18, 2, 3), | ||
216 | .clocks = CLOCKS("ref_crystal", | ||
217 | "var_104m", | ||
218 | "ref_104m", | ||
219 | "var_13m", | ||
220 | "ref_13m"), | ||
221 | .sel = SELECTOR(0x0a7c, 0, 3), | ||
222 | .trig = TRIGGER(0x0afc, 18), | ||
223 | }; | ||
224 | |||
225 | static struct peri_clk_data bsc4_data = { | ||
226 | .gate = HW_SW_GATE(0x0474, 18, 2, 3), | ||
227 | .clocks = CLOCKS("ref_crystal", | ||
228 | "var_104m", | ||
229 | "ref_104m", | ||
230 | "var_13m", | ||
231 | "ref_13m"), | ||
232 | .sel = SELECTOR(0x0a80, 0, 3), | ||
233 | .trig = TRIGGER(0x0afc, 19), | ||
234 | }; | ||
235 | |||
236 | static struct ccu_data slave_ccu_data = { | ||
237 | BCM21664_CCU_COMMON(slave, SLAVE), | ||
238 | .policy = { | ||
239 | .enable = CCU_LVM_EN(0x0034, 0), | ||
240 | .control = CCU_POLICY_CTL(0x000c, 0, 1, 2), | ||
241 | }, | ||
242 | .kona_clks = { | ||
243 | [BCM21664_SLAVE_CCU_UARTB] = | ||
244 | KONA_CLK(slave, uartb, peri), | ||
245 | [BCM21664_SLAVE_CCU_UARTB2] = | ||
246 | KONA_CLK(slave, uartb2, peri), | ||
247 | [BCM21664_SLAVE_CCU_UARTB3] = | ||
248 | KONA_CLK(slave, uartb3, peri), | ||
249 | [BCM21664_SLAVE_CCU_BSC1] = | ||
250 | KONA_CLK(slave, bsc1, peri), | ||
251 | [BCM21664_SLAVE_CCU_BSC2] = | ||
252 | KONA_CLK(slave, bsc2, peri), | ||
253 | [BCM21664_SLAVE_CCU_BSC3] = | ||
254 | KONA_CLK(slave, bsc3, peri), | ||
255 | [BCM21664_SLAVE_CCU_BSC4] = | ||
256 | KONA_CLK(slave, bsc4, peri), | ||
257 | [BCM21664_SLAVE_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
258 | }, | ||
259 | }; | ||
260 | |||
261 | /* Device tree match table callback functions */ | ||
262 | |||
263 | static void __init kona_dt_root_ccu_setup(struct device_node *node) | ||
264 | { | ||
265 | kona_dt_ccu_setup(&root_ccu_data, node); | ||
266 | } | ||
267 | |||
268 | static void __init kona_dt_aon_ccu_setup(struct device_node *node) | ||
269 | { | ||
270 | kona_dt_ccu_setup(&aon_ccu_data, node); | ||
271 | } | ||
272 | |||
273 | static void __init kona_dt_master_ccu_setup(struct device_node *node) | ||
274 | { | ||
275 | kona_dt_ccu_setup(&master_ccu_data, node); | ||
276 | } | ||
277 | |||
278 | static void __init kona_dt_slave_ccu_setup(struct device_node *node) | ||
279 | { | ||
280 | kona_dt_ccu_setup(&slave_ccu_data, node); | ||
281 | } | ||
282 | |||
283 | CLK_OF_DECLARE(bcm21664_root_ccu, BCM21664_DT_ROOT_CCU_COMPAT, | ||
284 | kona_dt_root_ccu_setup); | ||
285 | CLK_OF_DECLARE(bcm21664_aon_ccu, BCM21664_DT_AON_CCU_COMPAT, | ||
286 | kona_dt_aon_ccu_setup); | ||
287 | CLK_OF_DECLARE(bcm21664_master_ccu, BCM21664_DT_MASTER_CCU_COMPAT, | ||
288 | kona_dt_master_ccu_setup); | ||
289 | CLK_OF_DECLARE(bcm21664_slave_ccu, BCM21664_DT_SLAVE_CCU_COMPAT, | ||
290 | kona_dt_slave_ccu_setup); | ||
diff --git a/drivers/clk/bcm/clk-bcm281xx.c b/drivers/clk/bcm/clk-bcm281xx.c index 3c66de696aeb..502a487d62c5 100644 --- a/drivers/clk/bcm/clk-bcm281xx.c +++ b/drivers/clk/bcm/clk-bcm281xx.c | |||
@@ -15,14 +15,10 @@ | |||
15 | #include "clk-kona.h" | 15 | #include "clk-kona.h" |
16 | #include "dt-bindings/clock/bcm281xx.h" | 16 | #include "dt-bindings/clock/bcm281xx.h" |
17 | 17 | ||
18 | /* bcm11351 CCU device tree "compatible" strings */ | 18 | #define BCM281XX_CCU_COMMON(_name, _ucase_name) \ |
19 | #define BCM11351_DT_ROOT_CCU_COMPAT "brcm,bcm11351-root-ccu" | 19 | KONA_CCU_COMMON(BCM281XX, _name, _ucase_name) |
20 | #define BCM11351_DT_AON_CCU_COMPAT "brcm,bcm11351-aon-ccu" | ||
21 | #define BCM11351_DT_HUB_CCU_COMPAT "brcm,bcm11351-hub-ccu" | ||
22 | #define BCM11351_DT_MASTER_CCU_COMPAT "brcm,bcm11351-master-ccu" | ||
23 | #define BCM11351_DT_SLAVE_CCU_COMPAT "brcm,bcm11351-slave-ccu" | ||
24 | 20 | ||
25 | /* Root CCU clocks */ | 21 | /* Root CCU */ |
26 | 22 | ||
27 | static struct peri_clk_data frac_1m_data = { | 23 | static struct peri_clk_data frac_1m_data = { |
28 | .gate = HW_SW_GATE(0x214, 16, 0, 1), | 24 | .gate = HW_SW_GATE(0x214, 16, 0, 1), |
@@ -31,7 +27,16 @@ static struct peri_clk_data frac_1m_data = { | |||
31 | .clocks = CLOCKS("ref_crystal"), | 27 | .clocks = CLOCKS("ref_crystal"), |
32 | }; | 28 | }; |
33 | 29 | ||
34 | /* AON CCU clocks */ | 30 | static struct ccu_data root_ccu_data = { |
31 | BCM281XX_CCU_COMMON(root, ROOT), | ||
32 | .kona_clks = { | ||
33 | [BCM281XX_ROOT_CCU_FRAC_1M] = | ||
34 | KONA_CLK(root, frac_1m, peri), | ||
35 | [BCM281XX_ROOT_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
36 | }, | ||
37 | }; | ||
38 | |||
39 | /* AON CCU */ | ||
35 | 40 | ||
36 | static struct peri_clk_data hub_timer_data = { | 41 | static struct peri_clk_data hub_timer_data = { |
37 | .gate = HW_SW_GATE(0x0414, 16, 0, 1), | 42 | .gate = HW_SW_GATE(0x0414, 16, 0, 1), |
@@ -60,7 +65,20 @@ static struct peri_clk_data pmu_bsc_var_data = { | |||
60 | .trig = TRIGGER(0x0a40, 2), | 65 | .trig = TRIGGER(0x0a40, 2), |
61 | }; | 66 | }; |
62 | 67 | ||
63 | /* Hub CCU clocks */ | 68 | static struct ccu_data aon_ccu_data = { |
69 | BCM281XX_CCU_COMMON(aon, AON), | ||
70 | .kona_clks = { | ||
71 | [BCM281XX_AON_CCU_HUB_TIMER] = | ||
72 | KONA_CLK(aon, hub_timer, peri), | ||
73 | [BCM281XX_AON_CCU_PMU_BSC] = | ||
74 | KONA_CLK(aon, pmu_bsc, peri), | ||
75 | [BCM281XX_AON_CCU_PMU_BSC_VAR] = | ||
76 | KONA_CLK(aon, pmu_bsc_var, peri), | ||
77 | [BCM281XX_AON_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
78 | }, | ||
79 | }; | ||
80 | |||
81 | /* Hub CCU */ | ||
64 | 82 | ||
65 | static struct peri_clk_data tmon_1m_data = { | 83 | static struct peri_clk_data tmon_1m_data = { |
66 | .gate = HW_SW_GATE(0x04a4, 18, 2, 3), | 84 | .gate = HW_SW_GATE(0x04a4, 18, 2, 3), |
@@ -70,7 +88,16 @@ static struct peri_clk_data tmon_1m_data = { | |||
70 | .trig = TRIGGER(0x0e84, 1), | 88 | .trig = TRIGGER(0x0e84, 1), |
71 | }; | 89 | }; |
72 | 90 | ||
73 | /* Master CCU clocks */ | 91 | static struct ccu_data hub_ccu_data = { |
92 | BCM281XX_CCU_COMMON(hub, HUB), | ||
93 | .kona_clks = { | ||
94 | [BCM281XX_HUB_CCU_TMON_1M] = | ||
95 | KONA_CLK(hub, tmon_1m, peri), | ||
96 | [BCM281XX_HUB_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
97 | }, | ||
98 | }; | ||
99 | |||
100 | /* Master CCU */ | ||
74 | 101 | ||
75 | static struct peri_clk_data sdio1_data = { | 102 | static struct peri_clk_data sdio1_data = { |
76 | .gate = HW_SW_GATE(0x0358, 18, 2, 3), | 103 | .gate = HW_SW_GATE(0x0358, 18, 2, 3), |
@@ -153,7 +180,28 @@ static struct peri_clk_data hsic2_12m_data = { | |||
153 | .trig = TRIGGER(0x0afc, 5), | 180 | .trig = TRIGGER(0x0afc, 5), |
154 | }; | 181 | }; |
155 | 182 | ||
156 | /* Slave CCU clocks */ | 183 | static struct ccu_data master_ccu_data = { |
184 | BCM281XX_CCU_COMMON(master, MASTER), | ||
185 | .kona_clks = { | ||
186 | [BCM281XX_MASTER_CCU_SDIO1] = | ||
187 | KONA_CLK(master, sdio1, peri), | ||
188 | [BCM281XX_MASTER_CCU_SDIO2] = | ||
189 | KONA_CLK(master, sdio2, peri), | ||
190 | [BCM281XX_MASTER_CCU_SDIO3] = | ||
191 | KONA_CLK(master, sdio3, peri), | ||
192 | [BCM281XX_MASTER_CCU_SDIO4] = | ||
193 | KONA_CLK(master, sdio4, peri), | ||
194 | [BCM281XX_MASTER_CCU_USB_IC] = | ||
195 | KONA_CLK(master, usb_ic, peri), | ||
196 | [BCM281XX_MASTER_CCU_HSIC2_48M] = | ||
197 | KONA_CLK(master, hsic2_48m, peri), | ||
198 | [BCM281XX_MASTER_CCU_HSIC2_12M] = | ||
199 | KONA_CLK(master, hsic2_12m, peri), | ||
200 | [BCM281XX_MASTER_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | ||
201 | }, | ||
202 | }; | ||
203 | |||
204 | /* Slave CCU */ | ||
157 | 205 | ||
158 | static struct peri_clk_data uartb_data = { | 206 | static struct peri_clk_data uartb_data = { |
159 | .gate = HW_SW_GATE(0x0400, 18, 2, 3), | 207 | .gate = HW_SW_GATE(0x0400, 18, 2, 3), |
@@ -261,156 +309,67 @@ static struct peri_clk_data pwm_data = { | |||
261 | .trig = TRIGGER(0x0afc, 15), | 309 | .trig = TRIGGER(0x0afc, 15), |
262 | }; | 310 | }; |
263 | 311 | ||
264 | /* | 312 | static struct ccu_data slave_ccu_data = { |
265 | * CCU setup routines | 313 | BCM281XX_CCU_COMMON(slave, SLAVE), |
266 | * | 314 | .kona_clks = { |
267 | * These are called from kona_dt_ccu_setup() to initialize the array | 315 | [BCM281XX_SLAVE_CCU_UARTB] = |
268 | * of clocks provided by the CCU. Once allocated, the entries in | 316 | KONA_CLK(slave, uartb, peri), |
269 | * the array are initialized by calling kona_clk_setup() with the | 317 | [BCM281XX_SLAVE_CCU_UARTB2] = |
270 | * initialization data for each clock. They return 0 if successful | 318 | KONA_CLK(slave, uartb2, peri), |
271 | * or an error code otherwise. | 319 | [BCM281XX_SLAVE_CCU_UARTB3] = |
272 | */ | 320 | KONA_CLK(slave, uartb3, peri), |
273 | static int __init bcm281xx_root_ccu_clks_setup(struct ccu_data *ccu) | 321 | [BCM281XX_SLAVE_CCU_UARTB4] = |
274 | { | 322 | KONA_CLK(slave, uartb4, peri), |
275 | struct clk **clks; | 323 | [BCM281XX_SLAVE_CCU_SSP0] = |
276 | size_t count = BCM281XX_ROOT_CCU_CLOCK_COUNT; | 324 | KONA_CLK(slave, ssp0, peri), |
277 | 325 | [BCM281XX_SLAVE_CCU_SSP2] = | |
278 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | 326 | KONA_CLK(slave, ssp2, peri), |
279 | if (!clks) { | 327 | [BCM281XX_SLAVE_CCU_BSC1] = |
280 | pr_err("%s: failed to allocate root clocks\n", __func__); | 328 | KONA_CLK(slave, bsc1, peri), |
281 | return -ENOMEM; | 329 | [BCM281XX_SLAVE_CCU_BSC2] = |
282 | } | 330 | KONA_CLK(slave, bsc2, peri), |
283 | ccu->data.clks = clks; | 331 | [BCM281XX_SLAVE_CCU_BSC3] = |
284 | ccu->data.clk_num = count; | 332 | KONA_CLK(slave, bsc3, peri), |
285 | 333 | [BCM281XX_SLAVE_CCU_PWM] = | |
286 | PERI_CLK_SETUP(clks, ccu, BCM281XX_ROOT_CCU_FRAC_1M, frac_1m); | 334 | KONA_CLK(slave, pwm, peri), |
287 | 335 | [BCM281XX_SLAVE_CCU_CLOCK_COUNT] = LAST_KONA_CLK, | |
288 | return 0; | 336 | }, |
289 | } | 337 | }; |
290 | |||
291 | static int __init bcm281xx_aon_ccu_clks_setup(struct ccu_data *ccu) | ||
292 | { | ||
293 | struct clk **clks; | ||
294 | size_t count = BCM281XX_AON_CCU_CLOCK_COUNT; | ||
295 | |||
296 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
297 | if (!clks) { | ||
298 | pr_err("%s: failed to allocate aon clocks\n", __func__); | ||
299 | return -ENOMEM; | ||
300 | } | ||
301 | ccu->data.clks = clks; | ||
302 | ccu->data.clk_num = count; | ||
303 | |||
304 | PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_HUB_TIMER, hub_timer); | ||
305 | PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC, pmu_bsc); | ||
306 | PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC_VAR, pmu_bsc_var); | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int __init bcm281xx_hub_ccu_clks_setup(struct ccu_data *ccu) | ||
312 | { | ||
313 | struct clk **clks; | ||
314 | size_t count = BCM281XX_HUB_CCU_CLOCK_COUNT; | ||
315 | |||
316 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
317 | if (!clks) { | ||
318 | pr_err("%s: failed to allocate hub clocks\n", __func__); | ||
319 | return -ENOMEM; | ||
320 | } | ||
321 | ccu->data.clks = clks; | ||
322 | ccu->data.clk_num = count; | ||
323 | |||
324 | PERI_CLK_SETUP(clks, ccu, BCM281XX_HUB_CCU_TMON_1M, tmon_1m); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int __init bcm281xx_master_ccu_clks_setup(struct ccu_data *ccu) | ||
330 | { | ||
331 | struct clk **clks; | ||
332 | size_t count = BCM281XX_MASTER_CCU_CLOCK_COUNT; | ||
333 | |||
334 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
335 | if (!clks) { | ||
336 | pr_err("%s: failed to allocate master clocks\n", __func__); | ||
337 | return -ENOMEM; | ||
338 | } | ||
339 | ccu->data.clks = clks; | ||
340 | ccu->data.clk_num = count; | ||
341 | |||
342 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO1, sdio1); | ||
343 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO2, sdio2); | ||
344 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO3, sdio3); | ||
345 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO4, sdio4); | ||
346 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_USB_IC, usb_ic); | ||
347 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_48M, hsic2_48m); | ||
348 | PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_12M, hsic2_12m); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int __init bcm281xx_slave_ccu_clks_setup(struct ccu_data *ccu) | ||
354 | { | ||
355 | struct clk **clks; | ||
356 | size_t count = BCM281XX_SLAVE_CCU_CLOCK_COUNT; | ||
357 | |||
358 | clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); | ||
359 | if (!clks) { | ||
360 | pr_err("%s: failed to allocate slave clocks\n", __func__); | ||
361 | return -ENOMEM; | ||
362 | } | ||
363 | ccu->data.clks = clks; | ||
364 | ccu->data.clk_num = count; | ||
365 | |||
366 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB, uartb); | ||
367 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB2, uartb2); | ||
368 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB3, uartb3); | ||
369 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB4, uartb4); | ||
370 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP0, ssp0); | ||
371 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP2, ssp2); | ||
372 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC1, bsc1); | ||
373 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC2, bsc2); | ||
374 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC3, bsc3); | ||
375 | PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_PWM, pwm); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | 338 | ||
380 | /* Device tree match table callback functions */ | 339 | /* Device tree match table callback functions */ |
381 | 340 | ||
382 | static void __init kona_dt_root_ccu_setup(struct device_node *node) | 341 | static void __init kona_dt_root_ccu_setup(struct device_node *node) |
383 | { | 342 | { |
384 | kona_dt_ccu_setup(node, bcm281xx_root_ccu_clks_setup); | 343 | kona_dt_ccu_setup(&root_ccu_data, node); |
385 | } | 344 | } |
386 | 345 | ||
387 | static void __init kona_dt_aon_ccu_setup(struct device_node *node) | 346 | static void __init kona_dt_aon_ccu_setup(struct device_node *node) |
388 | { | 347 | { |
389 | kona_dt_ccu_setup(node, bcm281xx_aon_ccu_clks_setup); | 348 | kona_dt_ccu_setup(&aon_ccu_data, node); |
390 | } | 349 | } |
391 | 350 | ||
392 | static void __init kona_dt_hub_ccu_setup(struct device_node *node) | 351 | static void __init kona_dt_hub_ccu_setup(struct device_node *node) |
393 | { | 352 | { |
394 | kona_dt_ccu_setup(node, bcm281xx_hub_ccu_clks_setup); | 353 | kona_dt_ccu_setup(&hub_ccu_data, node); |
395 | } | 354 | } |
396 | 355 | ||
397 | static void __init kona_dt_master_ccu_setup(struct device_node *node) | 356 | static void __init kona_dt_master_ccu_setup(struct device_node *node) |
398 | { | 357 | { |
399 | kona_dt_ccu_setup(node, bcm281xx_master_ccu_clks_setup); | 358 | kona_dt_ccu_setup(&master_ccu_data, node); |
400 | } | 359 | } |
401 | 360 | ||
402 | static void __init kona_dt_slave_ccu_setup(struct device_node *node) | 361 | static void __init kona_dt_slave_ccu_setup(struct device_node *node) |
403 | { | 362 | { |
404 | kona_dt_ccu_setup(node, bcm281xx_slave_ccu_clks_setup); | 363 | kona_dt_ccu_setup(&slave_ccu_data, node); |
405 | } | 364 | } |
406 | 365 | ||
407 | CLK_OF_DECLARE(bcm11351_root_ccu, BCM11351_DT_ROOT_CCU_COMPAT, | 366 | CLK_OF_DECLARE(bcm281xx_root_ccu, BCM281XX_DT_ROOT_CCU_COMPAT, |
408 | kona_dt_root_ccu_setup); | 367 | kona_dt_root_ccu_setup); |
409 | CLK_OF_DECLARE(bcm11351_aon_ccu, BCM11351_DT_AON_CCU_COMPAT, | 368 | CLK_OF_DECLARE(bcm281xx_aon_ccu, BCM281XX_DT_AON_CCU_COMPAT, |
410 | kona_dt_aon_ccu_setup); | 369 | kona_dt_aon_ccu_setup); |
411 | CLK_OF_DECLARE(bcm11351_hub_ccu, BCM11351_DT_HUB_CCU_COMPAT, | 370 | CLK_OF_DECLARE(bcm281xx_hub_ccu, BCM281XX_DT_HUB_CCU_COMPAT, |
412 | kona_dt_hub_ccu_setup); | 371 | kona_dt_hub_ccu_setup); |
413 | CLK_OF_DECLARE(bcm11351_master_ccu, BCM11351_DT_MASTER_CCU_COMPAT, | 372 | CLK_OF_DECLARE(bcm281xx_master_ccu, BCM281XX_DT_MASTER_CCU_COMPAT, |
414 | kona_dt_master_ccu_setup); | 373 | kona_dt_master_ccu_setup); |
415 | CLK_OF_DECLARE(bcm11351_slave_ccu, BCM11351_DT_SLAVE_CCU_COMPAT, | 374 | CLK_OF_DECLARE(bcm281xx_slave_ccu, BCM281XX_DT_SLAVE_CCU_COMPAT, |
416 | kona_dt_slave_ccu_setup); | 375 | kona_dt_slave_ccu_setup); |
diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c index 54a06526f64f..e5aededdd322 100644 --- a/drivers/clk/bcm/clk-kona-setup.c +++ b/drivers/clk/bcm/clk-kona-setup.c | |||
@@ -25,6 +25,31 @@ LIST_HEAD(ccu_list); /* The list of set up CCUs */ | |||
25 | 25 | ||
26 | /* Validity checking */ | 26 | /* Validity checking */ |
27 | 27 | ||
28 | static bool ccu_data_offsets_valid(struct ccu_data *ccu) | ||
29 | { | ||
30 | struct ccu_policy *ccu_policy = &ccu->policy; | ||
31 | u32 limit; | ||
32 | |||
33 | limit = ccu->range - sizeof(u32); | ||
34 | limit = round_down(limit, sizeof(u32)); | ||
35 | if (ccu_policy_exists(ccu_policy)) { | ||
36 | if (ccu_policy->enable.offset > limit) { | ||
37 | pr_err("%s: bad policy enable offset for %s " | ||
38 | "(%u > %u)\n", __func__, | ||
39 | ccu->name, ccu_policy->enable.offset, limit); | ||
40 | return false; | ||
41 | } | ||
42 | if (ccu_policy->control.offset > limit) { | ||
43 | pr_err("%s: bad policy control offset for %s " | ||
44 | "(%u > %u)\n", __func__, | ||
45 | ccu->name, ccu_policy->control.offset, limit); | ||
46 | return false; | ||
47 | } | ||
48 | } | ||
49 | |||
50 | return true; | ||
51 | } | ||
52 | |||
28 | static bool clk_requires_trigger(struct kona_clk *bcm_clk) | 53 | static bool clk_requires_trigger(struct kona_clk *bcm_clk) |
29 | { | 54 | { |
30 | struct peri_clk_data *peri = bcm_clk->u.peri; | 55 | struct peri_clk_data *peri = bcm_clk->u.peri; |
@@ -54,7 +79,9 @@ static bool clk_requires_trigger(struct kona_clk *bcm_clk) | |||
54 | static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk) | 79 | static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk) |
55 | { | 80 | { |
56 | struct peri_clk_data *peri; | 81 | struct peri_clk_data *peri; |
82 | struct bcm_clk_policy *policy; | ||
57 | struct bcm_clk_gate *gate; | 83 | struct bcm_clk_gate *gate; |
84 | struct bcm_clk_hyst *hyst; | ||
58 | struct bcm_clk_div *div; | 85 | struct bcm_clk_div *div; |
59 | struct bcm_clk_sel *sel; | 86 | struct bcm_clk_sel *sel; |
60 | struct bcm_clk_trig *trig; | 87 | struct bcm_clk_trig *trig; |
@@ -64,19 +91,41 @@ static bool peri_clk_data_offsets_valid(struct kona_clk *bcm_clk) | |||
64 | 91 | ||
65 | BUG_ON(bcm_clk->type != bcm_clk_peri); | 92 | BUG_ON(bcm_clk->type != bcm_clk_peri); |
66 | peri = bcm_clk->u.peri; | 93 | peri = bcm_clk->u.peri; |
67 | name = bcm_clk->name; | 94 | name = bcm_clk->init_data.name; |
68 | range = bcm_clk->ccu->range; | 95 | range = bcm_clk->ccu->range; |
69 | 96 | ||
70 | limit = range - sizeof(u32); | 97 | limit = range - sizeof(u32); |
71 | limit = round_down(limit, sizeof(u32)); | 98 | limit = round_down(limit, sizeof(u32)); |
72 | 99 | ||
100 | policy = &peri->policy; | ||
101 | if (policy_exists(policy)) { | ||
102 | if (policy->offset > limit) { | ||
103 | pr_err("%s: bad policy offset for %s (%u > %u)\n", | ||
104 | __func__, name, policy->offset, limit); | ||
105 | return false; | ||
106 | } | ||
107 | } | ||
108 | |||
73 | gate = &peri->gate; | 109 | gate = &peri->gate; |
110 | hyst = &peri->hyst; | ||
74 | if (gate_exists(gate)) { | 111 | if (gate_exists(gate)) { |
75 | if (gate->offset > limit) { | 112 | if (gate->offset > limit) { |
76 | pr_err("%s: bad gate offset for %s (%u > %u)\n", | 113 | pr_err("%s: bad gate offset for %s (%u > %u)\n", |
77 | __func__, name, gate->offset, limit); | 114 | __func__, name, gate->offset, limit); |
78 | return false; | 115 | return false; |
79 | } | 116 | } |
117 | |||
118 | if (hyst_exists(hyst)) { | ||
119 | if (hyst->offset > limit) { | ||
120 | pr_err("%s: bad hysteresis offset for %s " | ||
121 | "(%u > %u)\n", __func__, | ||
122 | name, hyst->offset, limit); | ||
123 | return false; | ||
124 | } | ||
125 | } | ||
126 | } else if (hyst_exists(hyst)) { | ||
127 | pr_err("%s: hysteresis but no gate for %s\n", __func__, name); | ||
128 | return false; | ||
80 | } | 129 | } |
81 | 130 | ||
82 | div = &peri->div; | 131 | div = &peri->div; |
@@ -167,6 +216,36 @@ static bool bitfield_valid(u32 shift, u32 width, const char *field_name, | |||
167 | return true; | 216 | return true; |
168 | } | 217 | } |
169 | 218 | ||
219 | static bool | ||
220 | ccu_policy_valid(struct ccu_policy *ccu_policy, const char *ccu_name) | ||
221 | { | ||
222 | struct bcm_lvm_en *enable = &ccu_policy->enable; | ||
223 | struct bcm_policy_ctl *control; | ||
224 | |||
225 | if (!bit_posn_valid(enable->bit, "policy enable", ccu_name)) | ||
226 | return false; | ||
227 | |||
228 | control = &ccu_policy->control; | ||
229 | if (!bit_posn_valid(control->go_bit, "policy control GO", ccu_name)) | ||
230 | return false; | ||
231 | |||
232 | if (!bit_posn_valid(control->atl_bit, "policy control ATL", ccu_name)) | ||
233 | return false; | ||
234 | |||
235 | if (!bit_posn_valid(control->ac_bit, "policy control AC", ccu_name)) | ||
236 | return false; | ||
237 | |||
238 | return true; | ||
239 | } | ||
240 | |||
241 | static bool policy_valid(struct bcm_clk_policy *policy, const char *clock_name) | ||
242 | { | ||
243 | if (!bit_posn_valid(policy->bit, "policy", clock_name)) | ||
244 | return false; | ||
245 | |||
246 | return true; | ||
247 | } | ||
248 | |||
170 | /* | 249 | /* |
171 | * All gates, if defined, have a status bit, and for hardware-only | 250 | * All gates, if defined, have a status bit, and for hardware-only |
172 | * gates, that's it. Gates that can be software controlled also | 251 | * gates, that's it. Gates that can be software controlled also |
@@ -196,6 +275,17 @@ static bool gate_valid(struct bcm_clk_gate *gate, const char *field_name, | |||
196 | return true; | 275 | return true; |
197 | } | 276 | } |
198 | 277 | ||
278 | static bool hyst_valid(struct bcm_clk_hyst *hyst, const char *clock_name) | ||
279 | { | ||
280 | if (!bit_posn_valid(hyst->en_bit, "hysteresis enable", clock_name)) | ||
281 | return false; | ||
282 | |||
283 | if (!bit_posn_valid(hyst->val_bit, "hysteresis value", clock_name)) | ||
284 | return false; | ||
285 | |||
286 | return true; | ||
287 | } | ||
288 | |||
199 | /* | 289 | /* |
200 | * A selector bitfield must be valid. Its parent_sel array must | 290 | * A selector bitfield must be valid. Its parent_sel array must |
201 | * also be reasonable for the field. | 291 | * also be reasonable for the field. |
@@ -312,7 +402,9 @@ static bool | |||
312 | peri_clk_data_valid(struct kona_clk *bcm_clk) | 402 | peri_clk_data_valid(struct kona_clk *bcm_clk) |
313 | { | 403 | { |
314 | struct peri_clk_data *peri; | 404 | struct peri_clk_data *peri; |
405 | struct bcm_clk_policy *policy; | ||
315 | struct bcm_clk_gate *gate; | 406 | struct bcm_clk_gate *gate; |
407 | struct bcm_clk_hyst *hyst; | ||
316 | struct bcm_clk_sel *sel; | 408 | struct bcm_clk_sel *sel; |
317 | struct bcm_clk_div *div; | 409 | struct bcm_clk_div *div; |
318 | struct bcm_clk_div *pre_div; | 410 | struct bcm_clk_div *pre_div; |
@@ -330,11 +422,20 @@ peri_clk_data_valid(struct kona_clk *bcm_clk) | |||
330 | return false; | 422 | return false; |
331 | 423 | ||
332 | peri = bcm_clk->u.peri; | 424 | peri = bcm_clk->u.peri; |
333 | name = bcm_clk->name; | 425 | name = bcm_clk->init_data.name; |
426 | |||
427 | policy = &peri->policy; | ||
428 | if (policy_exists(policy) && !policy_valid(policy, name)) | ||
429 | return false; | ||
430 | |||
334 | gate = &peri->gate; | 431 | gate = &peri->gate; |
335 | if (gate_exists(gate) && !gate_valid(gate, "gate", name)) | 432 | if (gate_exists(gate) && !gate_valid(gate, "gate", name)) |
336 | return false; | 433 | return false; |
337 | 434 | ||
435 | hyst = &peri->hyst; | ||
436 | if (hyst_exists(hyst) && !hyst_valid(hyst, name)) | ||
437 | return false; | ||
438 | |||
338 | sel = &peri->sel; | 439 | sel = &peri->sel; |
339 | if (selector_exists(sel)) { | 440 | if (selector_exists(sel)) { |
340 | if (!sel_valid(sel, "selector", name)) | 441 | if (!sel_valid(sel, "selector", name)) |
@@ -567,7 +668,6 @@ static void peri_clk_teardown(struct peri_clk_data *data, | |||
567 | struct clk_init_data *init_data) | 668 | struct clk_init_data *init_data) |
568 | { | 669 | { |
569 | clk_sel_teardown(&data->sel, init_data); | 670 | clk_sel_teardown(&data->sel, init_data); |
570 | init_data->ops = NULL; | ||
571 | } | 671 | } |
572 | 672 | ||
573 | /* | 673 | /* |
@@ -576,10 +676,9 @@ static void peri_clk_teardown(struct peri_clk_data *data, | |||
576 | * that can be assigned if the clock has one or more parent clocks | 676 | * that can be assigned if the clock has one or more parent clocks |
577 | * associated with it. | 677 | * associated with it. |
578 | */ | 678 | */ |
579 | static int peri_clk_setup(struct ccu_data *ccu, struct peri_clk_data *data, | 679 | static int |
580 | struct clk_init_data *init_data) | 680 | peri_clk_setup(struct peri_clk_data *data, struct clk_init_data *init_data) |
581 | { | 681 | { |
582 | init_data->ops = &kona_peri_clk_ops; | ||
583 | init_data->flags = CLK_IGNORE_UNUSED; | 682 | init_data->flags = CLK_IGNORE_UNUSED; |
584 | 683 | ||
585 | return clk_sel_setup(data->clocks, &data->sel, init_data); | 684 | return clk_sel_setup(data->clocks, &data->sel, init_data); |
@@ -617,39 +716,26 @@ static void kona_clk_teardown(struct clk *clk) | |||
617 | bcm_clk_teardown(bcm_clk); | 716 | bcm_clk_teardown(bcm_clk); |
618 | } | 717 | } |
619 | 718 | ||
620 | struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | 719 | struct clk *kona_clk_setup(struct kona_clk *bcm_clk) |
621 | enum bcm_clk_type type, void *data) | ||
622 | { | 720 | { |
623 | struct kona_clk *bcm_clk; | 721 | struct clk_init_data *init_data = &bcm_clk->init_data; |
624 | struct clk_init_data *init_data; | ||
625 | struct clk *clk = NULL; | 722 | struct clk *clk = NULL; |
626 | 723 | ||
627 | bcm_clk = kzalloc(sizeof(*bcm_clk), GFP_KERNEL); | 724 | switch (bcm_clk->type) { |
628 | if (!bcm_clk) { | ||
629 | pr_err("%s: failed to allocate bcm_clk for %s\n", __func__, | ||
630 | name); | ||
631 | return NULL; | ||
632 | } | ||
633 | bcm_clk->ccu = ccu; | ||
634 | bcm_clk->name = name; | ||
635 | |||
636 | init_data = &bcm_clk->init_data; | ||
637 | init_data->name = name; | ||
638 | switch (type) { | ||
639 | case bcm_clk_peri: | 725 | case bcm_clk_peri: |
640 | if (peri_clk_setup(ccu, data, init_data)) | 726 | if (peri_clk_setup(bcm_clk->u.data, init_data)) |
641 | goto out_free; | 727 | return NULL; |
642 | break; | 728 | break; |
643 | default: | 729 | default: |
644 | data = NULL; | 730 | pr_err("%s: clock type %d invalid for %s\n", __func__, |
645 | break; | 731 | (int)bcm_clk->type, init_data->name); |
732 | return NULL; | ||
646 | } | 733 | } |
647 | bcm_clk->type = type; | ||
648 | bcm_clk->u.data = data; | ||
649 | 734 | ||
650 | /* Make sure everything makes sense before we set it up */ | 735 | /* Make sure everything makes sense before we set it up */ |
651 | if (!kona_clk_valid(bcm_clk)) { | 736 | if (!kona_clk_valid(bcm_clk)) { |
652 | pr_err("%s: clock data invalid for %s\n", __func__, name); | 737 | pr_err("%s: clock data invalid for %s\n", __func__, |
738 | init_data->name); | ||
653 | goto out_teardown; | 739 | goto out_teardown; |
654 | } | 740 | } |
655 | 741 | ||
@@ -657,7 +743,7 @@ struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | |||
657 | clk = clk_register(NULL, &bcm_clk->hw); | 743 | clk = clk_register(NULL, &bcm_clk->hw); |
658 | if (IS_ERR(clk)) { | 744 | if (IS_ERR(clk)) { |
659 | pr_err("%s: error registering clock %s (%ld)\n", __func__, | 745 | pr_err("%s: error registering clock %s (%ld)\n", __func__, |
660 | name, PTR_ERR(clk)); | 746 | init_data->name, PTR_ERR(clk)); |
661 | goto out_teardown; | 747 | goto out_teardown; |
662 | } | 748 | } |
663 | BUG_ON(!clk); | 749 | BUG_ON(!clk); |
@@ -665,8 +751,6 @@ struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | |||
665 | return clk; | 751 | return clk; |
666 | out_teardown: | 752 | out_teardown: |
667 | bcm_clk_teardown(bcm_clk); | 753 | bcm_clk_teardown(bcm_clk); |
668 | out_free: | ||
669 | kfree(bcm_clk); | ||
670 | 754 | ||
671 | return NULL; | 755 | return NULL; |
672 | } | 756 | } |
@@ -675,50 +759,64 @@ static void ccu_clks_teardown(struct ccu_data *ccu) | |||
675 | { | 759 | { |
676 | u32 i; | 760 | u32 i; |
677 | 761 | ||
678 | for (i = 0; i < ccu->data.clk_num; i++) | 762 | for (i = 0; i < ccu->clk_data.clk_num; i++) |
679 | kona_clk_teardown(ccu->data.clks[i]); | 763 | kona_clk_teardown(ccu->clk_data.clks[i]); |
680 | kfree(ccu->data.clks); | 764 | kfree(ccu->clk_data.clks); |
681 | } | 765 | } |
682 | 766 | ||
683 | static void kona_ccu_teardown(struct ccu_data *ccu) | 767 | static void kona_ccu_teardown(struct ccu_data *ccu) |
684 | { | 768 | { |
685 | if (!ccu) | 769 | kfree(ccu->clk_data.clks); |
686 | return; | 770 | ccu->clk_data.clks = NULL; |
687 | |||
688 | if (!ccu->base) | 771 | if (!ccu->base) |
689 | goto done; | 772 | return; |
690 | 773 | ||
691 | of_clk_del_provider(ccu->node); /* safe if never added */ | 774 | of_clk_del_provider(ccu->node); /* safe if never added */ |
692 | ccu_clks_teardown(ccu); | 775 | ccu_clks_teardown(ccu); |
693 | list_del(&ccu->links); | 776 | list_del(&ccu->links); |
694 | of_node_put(ccu->node); | 777 | of_node_put(ccu->node); |
778 | ccu->node = NULL; | ||
695 | iounmap(ccu->base); | 779 | iounmap(ccu->base); |
696 | done: | 780 | ccu->base = NULL; |
697 | kfree(ccu->name); | 781 | } |
698 | kfree(ccu); | 782 | |
783 | static bool ccu_data_valid(struct ccu_data *ccu) | ||
784 | { | ||
785 | struct ccu_policy *ccu_policy; | ||
786 | |||
787 | if (!ccu_data_offsets_valid(ccu)) | ||
788 | return false; | ||
789 | |||
790 | ccu_policy = &ccu->policy; | ||
791 | if (ccu_policy_exists(ccu_policy)) | ||
792 | if (!ccu_policy_valid(ccu_policy, ccu->name)) | ||
793 | return false; | ||
794 | |||
795 | return true; | ||
699 | } | 796 | } |
700 | 797 | ||
701 | /* | 798 | /* |
702 | * Set up a CCU. Call the provided ccu_clks_setup callback to | 799 | * Set up a CCU. Call the provided ccu_clks_setup callback to |
703 | * initialize the array of clocks provided by the CCU. | 800 | * initialize the array of clocks provided by the CCU. |
704 | */ | 801 | */ |
705 | void __init kona_dt_ccu_setup(struct device_node *node, | 802 | void __init kona_dt_ccu_setup(struct ccu_data *ccu, |
706 | int (*ccu_clks_setup)(struct ccu_data *)) | 803 | struct device_node *node) |
707 | { | 804 | { |
708 | struct ccu_data *ccu; | ||
709 | struct resource res = { 0 }; | 805 | struct resource res = { 0 }; |
710 | resource_size_t range; | 806 | resource_size_t range; |
807 | unsigned int i; | ||
711 | int ret; | 808 | int ret; |
712 | 809 | ||
713 | ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); | 810 | if (ccu->clk_data.clk_num) { |
714 | if (ccu) | 811 | size_t size; |
715 | ccu->name = kstrdup(node->name, GFP_KERNEL); | ||
716 | if (!ccu || !ccu->name) { | ||
717 | pr_err("%s: unable to allocate CCU struct for %s\n", | ||
718 | __func__, node->name); | ||
719 | kfree(ccu); | ||
720 | 812 | ||
721 | return; | 813 | size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks); |
814 | ccu->clk_data.clks = kzalloc(size, GFP_KERNEL); | ||
815 | if (!ccu->clk_data.clks) { | ||
816 | pr_err("%s: unable to allocate %u clocks for %s\n", | ||
817 | __func__, ccu->clk_data.clk_num, node->name); | ||
818 | return; | ||
819 | } | ||
722 | } | 820 | } |
723 | 821 | ||
724 | ret = of_address_to_resource(node, 0, &res); | 822 | ret = of_address_to_resource(node, 0, &res); |
@@ -736,24 +834,33 @@ void __init kona_dt_ccu_setup(struct device_node *node, | |||
736 | } | 834 | } |
737 | 835 | ||
738 | ccu->range = (u32)range; | 836 | ccu->range = (u32)range; |
837 | |||
838 | if (!ccu_data_valid(ccu)) { | ||
839 | pr_err("%s: ccu data not valid for %s\n", __func__, node->name); | ||
840 | goto out_err; | ||
841 | } | ||
842 | |||
739 | ccu->base = ioremap(res.start, ccu->range); | 843 | ccu->base = ioremap(res.start, ccu->range); |
740 | if (!ccu->base) { | 844 | if (!ccu->base) { |
741 | pr_err("%s: unable to map CCU registers for %s\n", __func__, | 845 | pr_err("%s: unable to map CCU registers for %s\n", __func__, |
742 | node->name); | 846 | node->name); |
743 | goto out_err; | 847 | goto out_err; |
744 | } | 848 | } |
745 | |||
746 | spin_lock_init(&ccu->lock); | ||
747 | INIT_LIST_HEAD(&ccu->links); | ||
748 | ccu->node = of_node_get(node); | 849 | ccu->node = of_node_get(node); |
749 | |||
750 | list_add_tail(&ccu->links, &ccu_list); | 850 | list_add_tail(&ccu->links, &ccu_list); |
751 | 851 | ||
752 | /* Set up clocks array (in ccu->data) */ | 852 | /* |
753 | if (ccu_clks_setup(ccu)) | 853 | * Set up each defined kona clock and save the result in |
754 | goto out_err; | 854 | * the clock framework clock array (in ccu->data). Then |
855 | * register as a provider for these clocks. | ||
856 | */ | ||
857 | for (i = 0; i < ccu->clk_data.clk_num; i++) { | ||
858 | if (!ccu->kona_clks[i].ccu) | ||
859 | continue; | ||
860 | ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]); | ||
861 | } | ||
755 | 862 | ||
756 | ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->data); | 863 | ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); |
757 | if (ret) { | 864 | if (ret) { |
758 | pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, | 865 | pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, |
759 | node->name, ret); | 866 | node->name, ret); |
diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c index db11a87449f2..95af2e665dd3 100644 --- a/drivers/clk/bcm/clk-kona.c +++ b/drivers/clk/bcm/clk-kona.c | |||
@@ -16,6 +16,14 @@ | |||
16 | 16 | ||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | 18 | ||
19 | /* | ||
20 | * "Policies" affect the frequencies of bus clocks provided by a | ||
21 | * CCU. (I believe these polices are named "Deep Sleep", "Economy", | ||
22 | * "Normal", and "Turbo".) A lower policy number has lower power | ||
23 | * consumption, and policy 2 is the default. | ||
24 | */ | ||
25 | #define CCU_POLICY_COUNT 4 | ||
26 | |||
19 | #define CCU_ACCESS_PASSWORD 0xA5A500 | 27 | #define CCU_ACCESS_PASSWORD 0xA5A500 |
20 | #define CLK_GATE_DELAY_LOOP 2000 | 28 | #define CLK_GATE_DELAY_LOOP 2000 |
21 | 29 | ||
@@ -207,9 +215,154 @@ __ccu_wait_bit(struct ccu_data *ccu, u32 reg_offset, u32 bit, bool want) | |||
207 | return true; | 215 | return true; |
208 | udelay(1); | 216 | udelay(1); |
209 | } | 217 | } |
218 | pr_warn("%s: %s/0x%04x bit %u was never %s\n", __func__, | ||
219 | ccu->name, reg_offset, bit, want ? "set" : "clear"); | ||
220 | |||
210 | return false; | 221 | return false; |
211 | } | 222 | } |
212 | 223 | ||
224 | /* Policy operations */ | ||
225 | |||
226 | static bool __ccu_policy_engine_start(struct ccu_data *ccu, bool sync) | ||
227 | { | ||
228 | struct bcm_policy_ctl *control = &ccu->policy.control; | ||
229 | u32 offset; | ||
230 | u32 go_bit; | ||
231 | u32 mask; | ||
232 | bool ret; | ||
233 | |||
234 | /* If we don't need to control policy for this CCU, we're done. */ | ||
235 | if (!policy_ctl_exists(control)) | ||
236 | return true; | ||
237 | |||
238 | offset = control->offset; | ||
239 | go_bit = control->go_bit; | ||
240 | |||
241 | /* Ensure we're not busy before we start */ | ||
242 | ret = __ccu_wait_bit(ccu, offset, go_bit, false); | ||
243 | if (!ret) { | ||
244 | pr_err("%s: ccu %s policy engine wouldn't go idle\n", | ||
245 | __func__, ccu->name); | ||
246 | return false; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * If it's a synchronous request, we'll wait for the voltage | ||
251 | * and frequency of the active load to stabilize before | ||
252 | * returning. To do this we select the active load by | ||
253 | * setting the ATL bit. | ||
254 | * | ||
255 | * An asynchronous request instead ramps the voltage in the | ||
256 | * background, and when that process stabilizes, the target | ||
257 | * load is copied to the active load and the CCU frequency | ||
258 | * is switched. We do this by selecting the target load | ||
259 | * (ATL bit clear) and setting the request auto-copy (AC bit | ||
260 | * set). | ||
261 | * | ||
262 | * Note, we do NOT read-modify-write this register. | ||
263 | */ | ||
264 | mask = (u32)1 << go_bit; | ||
265 | if (sync) | ||
266 | mask |= 1 << control->atl_bit; | ||
267 | else | ||
268 | mask |= 1 << control->ac_bit; | ||
269 | __ccu_write(ccu, offset, mask); | ||
270 | |||
271 | /* Wait for indication that operation is complete. */ | ||
272 | ret = __ccu_wait_bit(ccu, offset, go_bit, false); | ||
273 | if (!ret) | ||
274 | pr_err("%s: ccu %s policy engine never started\n", | ||
275 | __func__, ccu->name); | ||
276 | |||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | static bool __ccu_policy_engine_stop(struct ccu_data *ccu) | ||
281 | { | ||
282 | struct bcm_lvm_en *enable = &ccu->policy.enable; | ||
283 | u32 offset; | ||
284 | u32 enable_bit; | ||
285 | bool ret; | ||
286 | |||
287 | /* If we don't need to control policy for this CCU, we're done. */ | ||
288 | if (!policy_lvm_en_exists(enable)) | ||
289 | return true; | ||
290 | |||
291 | /* Ensure we're not busy before we start */ | ||
292 | offset = enable->offset; | ||
293 | enable_bit = enable->bit; | ||
294 | ret = __ccu_wait_bit(ccu, offset, enable_bit, false); | ||
295 | if (!ret) { | ||
296 | pr_err("%s: ccu %s policy engine already stopped\n", | ||
297 | __func__, ccu->name); | ||
298 | return false; | ||
299 | } | ||
300 | |||
301 | /* Now set the bit to stop the engine (NO read-modify-write) */ | ||
302 | __ccu_write(ccu, offset, (u32)1 << enable_bit); | ||
303 | |||
304 | /* Wait for indication that it has stopped. */ | ||
305 | ret = __ccu_wait_bit(ccu, offset, enable_bit, false); | ||
306 | if (!ret) | ||
307 | pr_err("%s: ccu %s policy engine never stopped\n", | ||
308 | __func__, ccu->name); | ||
309 | |||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * A CCU has four operating conditions ("policies"), and some clocks | ||
315 | * can be disabled or enabled based on which policy is currently in | ||
316 | * effect. Such clocks have a bit in a "policy mask" register for | ||
317 | * each policy indicating whether the clock is enabled for that | ||
318 | * policy or not. The bit position for a clock is the same for all | ||
319 | * four registers, and the 32-bit registers are at consecutive | ||
320 | * addresses. | ||
321 | */ | ||
322 | static bool policy_init(struct ccu_data *ccu, struct bcm_clk_policy *policy) | ||
323 | { | ||
324 | u32 offset; | ||
325 | u32 mask; | ||
326 | int i; | ||
327 | bool ret; | ||
328 | |||
329 | if (!policy_exists(policy)) | ||
330 | return true; | ||
331 | |||
332 | /* | ||
333 | * We need to stop the CCU policy engine to allow update | ||
334 | * of our policy bits. | ||
335 | */ | ||
336 | if (!__ccu_policy_engine_stop(ccu)) { | ||
337 | pr_err("%s: unable to stop CCU %s policy engine\n", | ||
338 | __func__, ccu->name); | ||
339 | return false; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * For now, if a clock defines its policy bit we just mark | ||
344 | * it "enabled" for all four policies. | ||
345 | */ | ||
346 | offset = policy->offset; | ||
347 | mask = (u32)1 << policy->bit; | ||
348 | for (i = 0; i < CCU_POLICY_COUNT; i++) { | ||
349 | u32 reg_val; | ||
350 | |||
351 | reg_val = __ccu_read(ccu, offset); | ||
352 | reg_val |= mask; | ||
353 | __ccu_write(ccu, offset, reg_val); | ||
354 | offset += sizeof(u32); | ||
355 | } | ||
356 | |||
357 | /* We're done updating; fire up the policy engine again. */ | ||
358 | ret = __ccu_policy_engine_start(ccu, true); | ||
359 | if (!ret) | ||
360 | pr_err("%s: unable to restart CCU %s policy engine\n", | ||
361 | __func__, ccu->name); | ||
362 | |||
363 | return ret; | ||
364 | } | ||
365 | |||
213 | /* Gate operations */ | 366 | /* Gate operations */ |
214 | 367 | ||
215 | /* Determine whether a clock is gated. CCU lock must be held. */ | 368 | /* Determine whether a clock is gated. CCU lock must be held. */ |
@@ -374,6 +527,35 @@ static int clk_gate(struct ccu_data *ccu, const char *name, | |||
374 | return -EIO; | 527 | return -EIO; |
375 | } | 528 | } |
376 | 529 | ||
530 | /* Hysteresis operations */ | ||
531 | |||
532 | /* | ||
533 | * If a clock gate requires a turn-off delay it will have | ||
534 | * "hysteresis" register bits defined. The first, if set, enables | ||
535 | * the delay; and if enabled, the second bit determines whether the | ||
536 | * delay is "low" or "high" (1 means high). For now, if it's | ||
537 | * defined for a clock, we set it. | ||
538 | */ | ||
539 | static bool hyst_init(struct ccu_data *ccu, struct bcm_clk_hyst *hyst) | ||
540 | { | ||
541 | u32 offset; | ||
542 | u32 reg_val; | ||
543 | u32 mask; | ||
544 | |||
545 | if (!hyst_exists(hyst)) | ||
546 | return true; | ||
547 | |||
548 | offset = hyst->offset; | ||
549 | mask = (u32)1 << hyst->en_bit; | ||
550 | mask |= (u32)1 << hyst->val_bit; | ||
551 | |||
552 | reg_val = __ccu_read(ccu, offset); | ||
553 | reg_val |= mask; | ||
554 | __ccu_write(ccu, offset, reg_val); | ||
555 | |||
556 | return true; | ||
557 | } | ||
558 | |||
377 | /* Trigger operations */ | 559 | /* Trigger operations */ |
378 | 560 | ||
379 | /* | 561 | /* |
@@ -806,7 +988,7 @@ static int kona_peri_clk_enable(struct clk_hw *hw) | |||
806 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 988 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
807 | struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; | 989 | struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; |
808 | 990 | ||
809 | return clk_gate(bcm_clk->ccu, bcm_clk->name, gate, true); | 991 | return clk_gate(bcm_clk->ccu, bcm_clk->init_data.name, gate, true); |
810 | } | 992 | } |
811 | 993 | ||
812 | static void kona_peri_clk_disable(struct clk_hw *hw) | 994 | static void kona_peri_clk_disable(struct clk_hw *hw) |
@@ -814,7 +996,7 @@ static void kona_peri_clk_disable(struct clk_hw *hw) | |||
814 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 996 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
815 | struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; | 997 | struct bcm_clk_gate *gate = &bcm_clk->u.peri->gate; |
816 | 998 | ||
817 | (void)clk_gate(bcm_clk->ccu, bcm_clk->name, gate, false); | 999 | (void)clk_gate(bcm_clk->ccu, bcm_clk->init_data.name, gate, false); |
818 | } | 1000 | } |
819 | 1001 | ||
820 | static int kona_peri_clk_is_enabled(struct clk_hw *hw) | 1002 | static int kona_peri_clk_is_enabled(struct clk_hw *hw) |
@@ -849,6 +1031,58 @@ static long kona_peri_clk_round_rate(struct clk_hw *hw, unsigned long rate, | |||
849 | rate ? rate : 1, *parent_rate, NULL); | 1031 | rate ? rate : 1, *parent_rate, NULL); |
850 | } | 1032 | } |
851 | 1033 | ||
1034 | static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate, | ||
1035 | unsigned long *best_parent_rate, struct clk **best_parent) | ||
1036 | { | ||
1037 | struct kona_clk *bcm_clk = to_kona_clk(hw); | ||
1038 | struct clk *clk = hw->clk; | ||
1039 | struct clk *current_parent; | ||
1040 | unsigned long parent_rate; | ||
1041 | unsigned long best_delta; | ||
1042 | unsigned long best_rate; | ||
1043 | u32 parent_count; | ||
1044 | u32 which; | ||
1045 | |||
1046 | /* | ||
1047 | * If there is no other parent to choose, use the current one. | ||
1048 | * Note: We don't honor (or use) CLK_SET_RATE_NO_REPARENT. | ||
1049 | */ | ||
1050 | WARN_ON_ONCE(bcm_clk->init_data.flags & CLK_SET_RATE_NO_REPARENT); | ||
1051 | parent_count = (u32)bcm_clk->init_data.num_parents; | ||
1052 | if (parent_count < 2) | ||
1053 | return kona_peri_clk_round_rate(hw, rate, best_parent_rate); | ||
1054 | |||
1055 | /* Unless we can do better, stick with current parent */ | ||
1056 | current_parent = clk_get_parent(clk); | ||
1057 | parent_rate = __clk_get_rate(current_parent); | ||
1058 | best_rate = kona_peri_clk_round_rate(hw, rate, &parent_rate); | ||
1059 | best_delta = abs(best_rate - rate); | ||
1060 | |||
1061 | /* Check whether any other parent clock can produce a better result */ | ||
1062 | for (which = 0; which < parent_count; which++) { | ||
1063 | struct clk *parent = clk_get_parent_by_index(clk, which); | ||
1064 | unsigned long delta; | ||
1065 | unsigned long other_rate; | ||
1066 | |||
1067 | BUG_ON(!parent); | ||
1068 | if (parent == current_parent) | ||
1069 | continue; | ||
1070 | |||
1071 | /* We don't support CLK_SET_RATE_PARENT */ | ||
1072 | parent_rate = __clk_get_rate(parent); | ||
1073 | other_rate = kona_peri_clk_round_rate(hw, rate, &parent_rate); | ||
1074 | delta = abs(other_rate - rate); | ||
1075 | if (delta < best_delta) { | ||
1076 | best_delta = delta; | ||
1077 | best_rate = other_rate; | ||
1078 | *best_parent = parent; | ||
1079 | *best_parent_rate = parent_rate; | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1083 | return best_rate; | ||
1084 | } | ||
1085 | |||
852 | static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index) | 1086 | static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index) |
853 | { | 1087 | { |
854 | struct kona_clk *bcm_clk = to_kona_clk(hw); | 1088 | struct kona_clk *bcm_clk = to_kona_clk(hw); |
@@ -872,12 +1106,13 @@ static int kona_peri_clk_set_parent(struct clk_hw *hw, u8 index) | |||
872 | 1106 | ||
873 | ret = selector_write(bcm_clk->ccu, &data->gate, sel, trig, index); | 1107 | ret = selector_write(bcm_clk->ccu, &data->gate, sel, trig, index); |
874 | if (ret == -ENXIO) { | 1108 | if (ret == -ENXIO) { |
875 | pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name); | 1109 | pr_err("%s: gating failure for %s\n", __func__, |
1110 | bcm_clk->init_data.name); | ||
876 | ret = -EIO; /* Don't proliferate weird errors */ | 1111 | ret = -EIO; /* Don't proliferate weird errors */ |
877 | } else if (ret == -EIO) { | 1112 | } else if (ret == -EIO) { |
878 | pr_err("%s: %strigger failed for %s\n", __func__, | 1113 | pr_err("%s: %strigger failed for %s\n", __func__, |
879 | trig == &data->pre_trig ? "pre-" : "", | 1114 | trig == &data->pre_trig ? "pre-" : "", |
880 | bcm_clk->name); | 1115 | bcm_clk->init_data.name); |
881 | } | 1116 | } |
882 | 1117 | ||
883 | return ret; | 1118 | return ret; |
@@ -936,10 +1171,12 @@ static int kona_peri_clk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
936 | ret = divider_write(bcm_clk->ccu, &data->gate, &data->div, | 1171 | ret = divider_write(bcm_clk->ccu, &data->gate, &data->div, |
937 | &data->trig, scaled_div); | 1172 | &data->trig, scaled_div); |
938 | if (ret == -ENXIO) { | 1173 | if (ret == -ENXIO) { |
939 | pr_err("%s: gating failure for %s\n", __func__, bcm_clk->name); | 1174 | pr_err("%s: gating failure for %s\n", __func__, |
1175 | bcm_clk->init_data.name); | ||
940 | ret = -EIO; /* Don't proliferate weird errors */ | 1176 | ret = -EIO; /* Don't proliferate weird errors */ |
941 | } else if (ret == -EIO) { | 1177 | } else if (ret == -EIO) { |
942 | pr_err("%s: trigger failed for %s\n", __func__, bcm_clk->name); | 1178 | pr_err("%s: trigger failed for %s\n", __func__, |
1179 | bcm_clk->init_data.name); | ||
943 | } | 1180 | } |
944 | 1181 | ||
945 | return ret; | 1182 | return ret; |
@@ -950,7 +1187,7 @@ struct clk_ops kona_peri_clk_ops = { | |||
950 | .disable = kona_peri_clk_disable, | 1187 | .disable = kona_peri_clk_disable, |
951 | .is_enabled = kona_peri_clk_is_enabled, | 1188 | .is_enabled = kona_peri_clk_is_enabled, |
952 | .recalc_rate = kona_peri_clk_recalc_rate, | 1189 | .recalc_rate = kona_peri_clk_recalc_rate, |
953 | .round_rate = kona_peri_clk_round_rate, | 1190 | .determine_rate = kona_peri_clk_determine_rate, |
954 | .set_parent = kona_peri_clk_set_parent, | 1191 | .set_parent = kona_peri_clk_set_parent, |
955 | .get_parent = kona_peri_clk_get_parent, | 1192 | .get_parent = kona_peri_clk_get_parent, |
956 | .set_rate = kona_peri_clk_set_rate, | 1193 | .set_rate = kona_peri_clk_set_rate, |
@@ -961,15 +1198,24 @@ static bool __peri_clk_init(struct kona_clk *bcm_clk) | |||
961 | { | 1198 | { |
962 | struct ccu_data *ccu = bcm_clk->ccu; | 1199 | struct ccu_data *ccu = bcm_clk->ccu; |
963 | struct peri_clk_data *peri = bcm_clk->u.peri; | 1200 | struct peri_clk_data *peri = bcm_clk->u.peri; |
964 | const char *name = bcm_clk->name; | 1201 | const char *name = bcm_clk->init_data.name; |
965 | struct bcm_clk_trig *trig; | 1202 | struct bcm_clk_trig *trig; |
966 | 1203 | ||
967 | BUG_ON(bcm_clk->type != bcm_clk_peri); | 1204 | BUG_ON(bcm_clk->type != bcm_clk_peri); |
968 | 1205 | ||
1206 | if (!policy_init(ccu, &peri->policy)) { | ||
1207 | pr_err("%s: error initializing policy for %s\n", | ||
1208 | __func__, name); | ||
1209 | return false; | ||
1210 | } | ||
969 | if (!gate_init(ccu, &peri->gate)) { | 1211 | if (!gate_init(ccu, &peri->gate)) { |
970 | pr_err("%s: error initializing gate for %s\n", __func__, name); | 1212 | pr_err("%s: error initializing gate for %s\n", __func__, name); |
971 | return false; | 1213 | return false; |
972 | } | 1214 | } |
1215 | if (!hyst_init(ccu, &peri->hyst)) { | ||
1216 | pr_err("%s: error initializing hyst for %s\n", __func__, name); | ||
1217 | return false; | ||
1218 | } | ||
973 | if (!div_init(ccu, &peri->gate, &peri->div, &peri->trig)) { | 1219 | if (!div_init(ccu, &peri->gate, &peri->div, &peri->trig)) { |
974 | pr_err("%s: error initializing divider for %s\n", __func__, | 1220 | pr_err("%s: error initializing divider for %s\n", __func__, |
975 | name); | 1221 | name); |
@@ -1014,13 +1260,13 @@ bool __init kona_ccu_init(struct ccu_data *ccu) | |||
1014 | { | 1260 | { |
1015 | unsigned long flags; | 1261 | unsigned long flags; |
1016 | unsigned int which; | 1262 | unsigned int which; |
1017 | struct clk **clks = ccu->data.clks; | 1263 | struct clk **clks = ccu->clk_data.clks; |
1018 | bool success = true; | 1264 | bool success = true; |
1019 | 1265 | ||
1020 | flags = ccu_lock(ccu); | 1266 | flags = ccu_lock(ccu); |
1021 | __ccu_write_enable(ccu); | 1267 | __ccu_write_enable(ccu); |
1022 | 1268 | ||
1023 | for (which = 0; which < ccu->data.clk_num; which++) { | 1269 | for (which = 0; which < ccu->clk_data.clk_num; which++) { |
1024 | struct kona_clk *bcm_clk; | 1270 | struct kona_clk *bcm_clk; |
1025 | 1271 | ||
1026 | if (!clks[which]) | 1272 | if (!clks[which]) |
diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h index dee690951bb6..2537b3072910 100644 --- a/drivers/clk/bcm/clk-kona.h +++ b/drivers/clk/bcm/clk-kona.h | |||
@@ -43,8 +43,14 @@ | |||
43 | #define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag)) | 43 | #define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag)) |
44 | #define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag))) | 44 | #define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag))) |
45 | 45 | ||
46 | /* CCU field state tests */ | ||
47 | |||
48 | #define ccu_policy_exists(ccu_policy) ((ccu_policy)->enable.offset != 0) | ||
49 | |||
46 | /* Clock field state tests */ | 50 | /* Clock field state tests */ |
47 | 51 | ||
52 | #define policy_exists(policy) ((policy)->offset != 0) | ||
53 | |||
48 | #define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS) | 54 | #define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS) |
49 | #define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED) | 55 | #define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED) |
50 | #define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW) | 56 | #define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW) |
@@ -54,6 +60,8 @@ | |||
54 | 60 | ||
55 | #define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED) | 61 | #define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED) |
56 | 62 | ||
63 | #define hyst_exists(hyst) ((hyst)->offset != 0) | ||
64 | |||
57 | #define divider_exists(div) FLAG_TEST(div, DIV, EXISTS) | 65 | #define divider_exists(div) FLAG_TEST(div, DIV, EXISTS) |
58 | #define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED) | 66 | #define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED) |
59 | #define divider_has_fraction(div) (!divider_is_fixed(div) && \ | 67 | #define divider_has_fraction(div) (!divider_is_fixed(div) && \ |
@@ -62,6 +70,9 @@ | |||
62 | #define selector_exists(sel) ((sel)->width != 0) | 70 | #define selector_exists(sel) ((sel)->width != 0) |
63 | #define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS) | 71 | #define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS) |
64 | 72 | ||
73 | #define policy_lvm_en_exists(enable) ((enable)->offset != 0) | ||
74 | #define policy_ctl_exists(control) ((control)->offset != 0) | ||
75 | |||
65 | /* Clock type, used to tell common block what it's part of */ | 76 | /* Clock type, used to tell common block what it's part of */ |
66 | enum bcm_clk_type { | 77 | enum bcm_clk_type { |
67 | bcm_clk_none, /* undefined clock type */ | 78 | bcm_clk_none, /* undefined clock type */ |
@@ -71,25 +82,26 @@ enum bcm_clk_type { | |||
71 | }; | 82 | }; |
72 | 83 | ||
73 | /* | 84 | /* |
74 | * Each CCU defines a mapped area of memory containing registers | 85 | * CCU policy control for clocks. Clocks can be enabled or disabled |
75 | * used to manage clocks implemented by the CCU. Access to memory | 86 | * based on the CCU policy in effect. One bit in each policy mask |
76 | * within the CCU's space is serialized by a spinlock. Before any | 87 | * register (one per CCU policy) represents whether the clock is |
77 | * (other) address can be written, a special access "password" value | 88 | * enabled when that policy is effect or not. The CCU policy engine |
78 | * must be written to its WR_ACCESS register (located at the base | 89 | * must be stopped to update these bits, and must be restarted again |
79 | * address of the range). We keep track of the name of each CCU as | 90 | * afterward. |
80 | * it is set up, and maintain them in a list. | ||
81 | */ | 91 | */ |
82 | struct ccu_data { | 92 | struct bcm_clk_policy { |
83 | void __iomem *base; /* base of mapped address space */ | 93 | u32 offset; /* first policy mask register offset */ |
84 | spinlock_t lock; /* serialization lock */ | 94 | u32 bit; /* bit used in all mask registers */ |
85 | bool write_enabled; /* write access is currently enabled */ | ||
86 | struct list_head links; /* for ccu_list */ | ||
87 | struct device_node *node; | ||
88 | struct clk_onecell_data data; | ||
89 | const char *name; | ||
90 | u32 range; /* byte range of address space */ | ||
91 | }; | 95 | }; |
92 | 96 | ||
97 | /* Policy initialization macro */ | ||
98 | |||
99 | #define POLICY(_offset, _bit) \ | ||
100 | { \ | ||
101 | .offset = (_offset), \ | ||
102 | .bit = (_bit), \ | ||
103 | } | ||
104 | |||
93 | /* | 105 | /* |
94 | * Gating control and status is managed by a 32-bit gate register. | 106 | * Gating control and status is managed by a 32-bit gate register. |
95 | * | 107 | * |
@@ -195,6 +207,22 @@ struct bcm_clk_gate { | |||
195 | .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \ | 207 | .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \ |
196 | } | 208 | } |
197 | 209 | ||
210 | /* Gate hysteresis for clocks */ | ||
211 | struct bcm_clk_hyst { | ||
212 | u32 offset; /* hyst register offset (normally CLKGATE) */ | ||
213 | u32 en_bit; /* bit used to enable hysteresis */ | ||
214 | u32 val_bit; /* if enabled: 0 = low delay; 1 = high delay */ | ||
215 | }; | ||
216 | |||
217 | /* Hysteresis initialization macro */ | ||
218 | |||
219 | #define HYST(_offset, _en_bit, _val_bit) \ | ||
220 | { \ | ||
221 | .offset = (_offset), \ | ||
222 | .en_bit = (_en_bit), \ | ||
223 | .val_bit = (_val_bit), \ | ||
224 | } | ||
225 | |||
198 | /* | 226 | /* |
199 | * Each clock can have zero, one, or two dividers which change the | 227 | * Each clock can have zero, one, or two dividers which change the |
200 | * output rate of the clock. Each divider can be either fixed or | 228 | * output rate of the clock. Each divider can be either fixed or |
@@ -360,7 +388,9 @@ struct bcm_clk_trig { | |||
360 | } | 388 | } |
361 | 389 | ||
362 | struct peri_clk_data { | 390 | struct peri_clk_data { |
391 | struct bcm_clk_policy policy; | ||
363 | struct bcm_clk_gate gate; | 392 | struct bcm_clk_gate gate; |
393 | struct bcm_clk_hyst hyst; | ||
364 | struct bcm_clk_trig pre_trig; | 394 | struct bcm_clk_trig pre_trig; |
365 | struct bcm_clk_div pre_div; | 395 | struct bcm_clk_div pre_div; |
366 | struct bcm_clk_trig trig; | 396 | struct bcm_clk_trig trig; |
@@ -373,8 +403,7 @@ struct peri_clk_data { | |||
373 | 403 | ||
374 | struct kona_clk { | 404 | struct kona_clk { |
375 | struct clk_hw hw; | 405 | struct clk_hw hw; |
376 | struct clk_init_data init_data; | 406 | struct clk_init_data init_data; /* includes name of this clock */ |
377 | const char *name; /* name of this clock */ | ||
378 | struct ccu_data *ccu; /* ccu this clock is associated with */ | 407 | struct ccu_data *ccu; /* ccu this clock is associated with */ |
379 | enum bcm_clk_type type; | 408 | enum bcm_clk_type type; |
380 | union { | 409 | union { |
@@ -385,14 +414,92 @@ struct kona_clk { | |||
385 | #define to_kona_clk(_hw) \ | 414 | #define to_kona_clk(_hw) \ |
386 | container_of(_hw, struct kona_clk, hw) | 415 | container_of(_hw, struct kona_clk, hw) |
387 | 416 | ||
388 | /* Exported globals */ | 417 | /* Initialization macro for an entry in a CCU's kona_clks[] array. */ |
418 | #define KONA_CLK(_ccu_name, _clk_name, _type) \ | ||
419 | { \ | ||
420 | .init_data = { \ | ||
421 | .name = #_clk_name, \ | ||
422 | .ops = &kona_ ## _type ## _clk_ops, \ | ||
423 | }, \ | ||
424 | .ccu = &_ccu_name ## _ccu_data, \ | ||
425 | .type = bcm_clk_ ## _type, \ | ||
426 | .u.data = &_clk_name ## _data, \ | ||
427 | } | ||
428 | #define LAST_KONA_CLK { .type = bcm_clk_none } | ||
389 | 429 | ||
390 | extern struct clk_ops kona_peri_clk_ops; | 430 | /* |
431 | * CCU policy control. To enable software update of the policy | ||
432 | * tables the CCU policy engine must be stopped by setting the | ||
433 | * software update enable bit (LVM_EN). After an update the engine | ||
434 | * is restarted using the GO bit and either the GO_ATL or GO_AC bit. | ||
435 | */ | ||
436 | struct bcm_lvm_en { | ||
437 | u32 offset; /* LVM_EN register offset */ | ||
438 | u32 bit; /* POLICY_CONFIG_EN bit in register */ | ||
439 | }; | ||
440 | |||
441 | /* Policy enable initialization macro */ | ||
442 | #define CCU_LVM_EN(_offset, _bit) \ | ||
443 | { \ | ||
444 | .offset = (_offset), \ | ||
445 | .bit = (_bit), \ | ||
446 | } | ||
447 | |||
448 | struct bcm_policy_ctl { | ||
449 | u32 offset; /* POLICY_CTL register offset */ | ||
450 | u32 go_bit; | ||
451 | u32 atl_bit; /* GO, GO_ATL, and GO_AC bits */ | ||
452 | u32 ac_bit; | ||
453 | }; | ||
454 | |||
455 | /* Policy control initialization macro */ | ||
456 | #define CCU_POLICY_CTL(_offset, _go_bit, _ac_bit, _atl_bit) \ | ||
457 | { \ | ||
458 | .offset = (_offset), \ | ||
459 | .go_bit = (_go_bit), \ | ||
460 | .ac_bit = (_ac_bit), \ | ||
461 | .atl_bit = (_atl_bit), \ | ||
462 | } | ||
463 | |||
464 | struct ccu_policy { | ||
465 | struct bcm_lvm_en enable; | ||
466 | struct bcm_policy_ctl control; | ||
467 | }; | ||
468 | |||
469 | /* | ||
470 | * Each CCU defines a mapped area of memory containing registers | ||
471 | * used to manage clocks implemented by the CCU. Access to memory | ||
472 | * within the CCU's space is serialized by a spinlock. Before any | ||
473 | * (other) address can be written, a special access "password" value | ||
474 | * must be written to its WR_ACCESS register (located at the base | ||
475 | * address of the range). We keep track of the name of each CCU as | ||
476 | * it is set up, and maintain them in a list. | ||
477 | */ | ||
478 | struct ccu_data { | ||
479 | void __iomem *base; /* base of mapped address space */ | ||
480 | spinlock_t lock; /* serialization lock */ | ||
481 | bool write_enabled; /* write access is currently enabled */ | ||
482 | struct ccu_policy policy; | ||
483 | struct list_head links; /* for ccu_list */ | ||
484 | struct device_node *node; | ||
485 | struct clk_onecell_data clk_data; | ||
486 | const char *name; | ||
487 | u32 range; /* byte range of address space */ | ||
488 | struct kona_clk kona_clks[]; /* must be last */ | ||
489 | }; | ||
391 | 490 | ||
392 | /* Help functions */ | 491 | /* Initialization for common fields in a Kona ccu_data structure */ |
492 | #define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ | ||
493 | .name = #_name "_ccu", \ | ||
494 | .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ | ||
495 | .links = LIST_HEAD_INIT(_name ## _ccu_data.links), \ | ||
496 | .clk_data = { \ | ||
497 | .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \ | ||
498 | } | ||
499 | |||
500 | /* Exported globals */ | ||
393 | 501 | ||
394 | #define PERI_CLK_SETUP(clks, ccu, id, name) \ | 502 | extern struct clk_ops kona_peri_clk_ops; |
395 | clks[id] = kona_clk_setup(ccu, #name, bcm_clk_peri, &name ## _data) | ||
396 | 503 | ||
397 | /* Externally visible functions */ | 504 | /* Externally visible functions */ |
398 | 505 | ||
@@ -401,10 +508,9 @@ extern u64 scaled_div_max(struct bcm_clk_div *div); | |||
401 | extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, | 508 | extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, |
402 | u32 billionths); | 509 | u32 billionths); |
403 | 510 | ||
404 | extern struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, | 511 | extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk); |
405 | enum bcm_clk_type type, void *data); | 512 | extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, |
406 | extern void __init kona_dt_ccu_setup(struct device_node *node, | 513 | struct device_node *node); |
407 | int (*ccu_clks_setup)(struct ccu_data *)); | ||
408 | extern bool __init kona_ccu_init(struct ccu_data *ccu); | 514 | extern bool __init kona_ccu_init(struct ccu_data *ccu); |
409 | 515 | ||
410 | #endif /* _CLK_KONA_H */ | 516 | #endif /* _CLK_KONA_H */ |