1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. |
4 | */ |
5 | |
6 | #include <linux/clkdev.h> |
7 | #include <linux/clk.h> |
8 | #include <linux/clk-provider.h> |
9 | #include <linux/delay.h> |
10 | #include <linux/io.h> |
11 | #include <linux/of.h> |
12 | #include <linux/of_platform.h> |
13 | #include <linux/clk/tegra.h> |
14 | #include <linux/platform_device.h> |
15 | #include <linux/pm_runtime.h> |
16 | #include <linux/reset-controller.h> |
17 | #include <linux/string_helpers.h> |
18 | |
19 | #include <soc/tegra/fuse.h> |
20 | |
21 | #include "clk.h" |
22 | |
23 | /* Global data of Tegra CPU CAR ops */ |
24 | static struct device_node *tegra_car_np; |
25 | static struct tegra_cpu_car_ops dummy_car_ops; |
26 | struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops; |
27 | |
28 | int *periph_clk_enb_refcnt; |
29 | static int periph_banks; |
30 | static u32 *periph_state_ctx; |
31 | static struct clk **clks; |
32 | static int clk_num; |
33 | static struct clk_onecell_data clk_data; |
34 | |
35 | /* Handlers for SoC-specific reset lines */ |
36 | static int (*special_reset_assert)(unsigned long); |
37 | static int (*special_reset_deassert)(unsigned long); |
38 | static unsigned int num_special_reset; |
39 | |
40 | static const struct tegra_clk_periph_regs periph_regs[] = { |
41 | [0] = { |
42 | .enb_reg = CLK_OUT_ENB_L, |
43 | .enb_set_reg = CLK_OUT_ENB_SET_L, |
44 | .enb_clr_reg = CLK_OUT_ENB_CLR_L, |
45 | .rst_reg = RST_DEVICES_L, |
46 | .rst_set_reg = RST_DEVICES_SET_L, |
47 | .rst_clr_reg = RST_DEVICES_CLR_L, |
48 | }, |
49 | [1] = { |
50 | .enb_reg = CLK_OUT_ENB_H, |
51 | .enb_set_reg = CLK_OUT_ENB_SET_H, |
52 | .enb_clr_reg = CLK_OUT_ENB_CLR_H, |
53 | .rst_reg = RST_DEVICES_H, |
54 | .rst_set_reg = RST_DEVICES_SET_H, |
55 | .rst_clr_reg = RST_DEVICES_CLR_H, |
56 | }, |
57 | [2] = { |
58 | .enb_reg = CLK_OUT_ENB_U, |
59 | .enb_set_reg = CLK_OUT_ENB_SET_U, |
60 | .enb_clr_reg = CLK_OUT_ENB_CLR_U, |
61 | .rst_reg = RST_DEVICES_U, |
62 | .rst_set_reg = RST_DEVICES_SET_U, |
63 | .rst_clr_reg = RST_DEVICES_CLR_U, |
64 | }, |
65 | [3] = { |
66 | .enb_reg = CLK_OUT_ENB_V, |
67 | .enb_set_reg = CLK_OUT_ENB_SET_V, |
68 | .enb_clr_reg = CLK_OUT_ENB_CLR_V, |
69 | .rst_reg = RST_DEVICES_V, |
70 | .rst_set_reg = RST_DEVICES_SET_V, |
71 | .rst_clr_reg = RST_DEVICES_CLR_V, |
72 | }, |
73 | [4] = { |
74 | .enb_reg = CLK_OUT_ENB_W, |
75 | .enb_set_reg = CLK_OUT_ENB_SET_W, |
76 | .enb_clr_reg = CLK_OUT_ENB_CLR_W, |
77 | .rst_reg = RST_DEVICES_W, |
78 | .rst_set_reg = RST_DEVICES_SET_W, |
79 | .rst_clr_reg = RST_DEVICES_CLR_W, |
80 | }, |
81 | [5] = { |
82 | .enb_reg = CLK_OUT_ENB_X, |
83 | .enb_set_reg = CLK_OUT_ENB_SET_X, |
84 | .enb_clr_reg = CLK_OUT_ENB_CLR_X, |
85 | .rst_reg = RST_DEVICES_X, |
86 | .rst_set_reg = RST_DEVICES_SET_X, |
87 | .rst_clr_reg = RST_DEVICES_CLR_X, |
88 | }, |
89 | [6] = { |
90 | .enb_reg = CLK_OUT_ENB_Y, |
91 | .enb_set_reg = CLK_OUT_ENB_SET_Y, |
92 | .enb_clr_reg = CLK_OUT_ENB_CLR_Y, |
93 | .rst_reg = RST_DEVICES_Y, |
94 | .rst_set_reg = RST_DEVICES_SET_Y, |
95 | .rst_clr_reg = RST_DEVICES_CLR_Y, |
96 | }, |
97 | }; |
98 | |
99 | static void __iomem *clk_base; |
100 | |
101 | static int tegra_clk_rst_assert(struct reset_controller_dev *rcdev, |
102 | unsigned long id) |
103 | { |
104 | /* |
105 | * If peripheral is on the APB bus then we must read the APB bus to |
106 | * flush the write operation in apb bus. This will avoid peripheral |
107 | * access after disabling clock. Since the reset driver has no |
108 | * knowledge of which reset IDs represent which devices, simply do |
109 | * this all the time. |
110 | */ |
111 | tegra_read_chipid(); |
112 | |
113 | if (id < periph_banks * 32) { |
114 | writel_relaxed(BIT(id % 32), |
115 | clk_base + periph_regs[id / 32].rst_set_reg); |
116 | return 0; |
117 | } else if (id < periph_banks * 32 + num_special_reset) { |
118 | return special_reset_assert(id); |
119 | } |
120 | |
121 | return -EINVAL; |
122 | } |
123 | |
124 | static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev, |
125 | unsigned long id) |
126 | { |
127 | if (id < periph_banks * 32) { |
128 | writel_relaxed(BIT(id % 32), |
129 | clk_base + periph_regs[id / 32].rst_clr_reg); |
130 | return 0; |
131 | } else if (id < periph_banks * 32 + num_special_reset) { |
132 | return special_reset_deassert(id); |
133 | } |
134 | |
135 | return -EINVAL; |
136 | } |
137 | |
138 | static int tegra_clk_rst_reset(struct reset_controller_dev *rcdev, |
139 | unsigned long id) |
140 | { |
141 | int err; |
142 | |
143 | err = tegra_clk_rst_assert(rcdev, id); |
144 | if (err) |
145 | return err; |
146 | |
147 | udelay(1); |
148 | |
149 | return tegra_clk_rst_deassert(rcdev, id); |
150 | } |
151 | |
152 | const struct tegra_clk_periph_regs *get_reg_bank(int clkid) |
153 | { |
154 | int reg_bank = clkid / 32; |
155 | |
156 | if (reg_bank < periph_banks) |
157 | return &periph_regs[reg_bank]; |
158 | else { |
159 | WARN_ON(1); |
160 | return NULL; |
161 | } |
162 | } |
163 | |
164 | void tegra_clk_set_pllp_out_cpu(bool enable) |
165 | { |
166 | u32 val; |
167 | |
168 | val = readl_relaxed(clk_base + CLK_OUT_ENB_Y); |
169 | if (enable) |
170 | val |= CLK_ENB_PLLP_OUT_CPU; |
171 | else |
172 | val &= ~CLK_ENB_PLLP_OUT_CPU; |
173 | |
174 | writel_relaxed(val, clk_base + CLK_OUT_ENB_Y); |
175 | } |
176 | |
177 | void tegra_clk_periph_suspend(void) |
178 | { |
179 | unsigned int i, idx; |
180 | |
181 | idx = 0; |
182 | for (i = 0; i < periph_banks; i++, idx++) |
183 | periph_state_ctx[idx] = |
184 | readl_relaxed(clk_base + periph_regs[i].enb_reg); |
185 | |
186 | for (i = 0; i < periph_banks; i++, idx++) |
187 | periph_state_ctx[idx] = |
188 | readl_relaxed(clk_base + periph_regs[i].rst_reg); |
189 | } |
190 | |
191 | void tegra_clk_periph_resume(void) |
192 | { |
193 | unsigned int i, idx; |
194 | |
195 | idx = 0; |
196 | for (i = 0; i < periph_banks; i++, idx++) |
197 | writel_relaxed(periph_state_ctx[idx], |
198 | clk_base + periph_regs[i].enb_reg); |
199 | /* |
200 | * All non-boot peripherals will be in reset state on resume. |
201 | * Wait for 5us of reset propagation delay before de-asserting |
202 | * the peripherals based on the saved context. |
203 | */ |
204 | fence_udelay(5, clk_base); |
205 | |
206 | for (i = 0; i < periph_banks; i++, idx++) |
207 | writel_relaxed(periph_state_ctx[idx], |
208 | clk_base + periph_regs[i].rst_reg); |
209 | |
210 | fence_udelay(2, clk_base); |
211 | } |
212 | |
213 | static int tegra_clk_periph_ctx_init(int banks) |
214 | { |
215 | periph_state_ctx = kcalloc(n: 2 * banks, size: sizeof(*periph_state_ctx), |
216 | GFP_KERNEL); |
217 | if (!periph_state_ctx) |
218 | return -ENOMEM; |
219 | |
220 | return 0; |
221 | } |
222 | |
223 | struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) |
224 | { |
225 | clk_base = regs; |
226 | |
227 | if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) |
228 | return NULL; |
229 | |
230 | periph_clk_enb_refcnt = kcalloc(n: 32 * banks, |
231 | size: sizeof(*periph_clk_enb_refcnt), |
232 | GFP_KERNEL); |
233 | if (!periph_clk_enb_refcnt) |
234 | return NULL; |
235 | |
236 | periph_banks = banks; |
237 | |
238 | clks = kcalloc(n: num, size: sizeof(struct clk *), GFP_KERNEL); |
239 | if (!clks) { |
240 | kfree(objp: periph_clk_enb_refcnt); |
241 | return NULL; |
242 | } |
243 | |
244 | clk_num = num; |
245 | |
246 | if (IS_ENABLED(CONFIG_PM_SLEEP)) { |
247 | if (tegra_clk_periph_ctx_init(banks)) { |
248 | kfree(objp: periph_clk_enb_refcnt); |
249 | kfree(objp: clks); |
250 | return NULL; |
251 | } |
252 | } |
253 | |
254 | return clks; |
255 | } |
256 | |
257 | void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, |
258 | struct clk *clks[], int clk_max) |
259 | { |
260 | struct clk *clk; |
261 | |
262 | for (; dup_list->clk_id < clk_max; dup_list++) { |
263 | clk = clks[dup_list->clk_id]; |
264 | dup_list->lookup.clk = clk; |
265 | clkdev_add(cl: &dup_list->lookup); |
266 | } |
267 | } |
268 | |
269 | void tegra_init_from_table(struct tegra_clk_init_table *tbl, |
270 | struct clk *clks[], int clk_max) |
271 | { |
272 | struct clk *clk; |
273 | |
274 | for (; tbl->clk_id < clk_max; tbl++) { |
275 | clk = clks[tbl->clk_id]; |
276 | if (IS_ERR_OR_NULL(ptr: clk)) { |
277 | pr_err("%s: invalid entry %ld in clks array for id %d\n" , |
278 | __func__, PTR_ERR(clk), tbl->clk_id); |
279 | WARN_ON(1); |
280 | |
281 | continue; |
282 | } |
283 | |
284 | if (tbl->parent_id < clk_max) { |
285 | struct clk *parent = clks[tbl->parent_id]; |
286 | if (clk_set_parent(clk, parent)) { |
287 | pr_err("%s: Failed to set parent %s of %s\n" , |
288 | __func__, __clk_get_name(parent), |
289 | __clk_get_name(clk)); |
290 | WARN_ON(1); |
291 | } |
292 | } |
293 | |
294 | if (tbl->rate) |
295 | if (clk_set_rate(clk, rate: tbl->rate)) { |
296 | pr_err("%s: Failed to set rate %lu of %s\n" , |
297 | __func__, tbl->rate, |
298 | __clk_get_name(clk)); |
299 | WARN_ON(1); |
300 | } |
301 | |
302 | if (tbl->state) |
303 | if (clk_prepare_enable(clk)) { |
304 | pr_err("%s: Failed to enable %s\n" , __func__, |
305 | __clk_get_name(clk)); |
306 | WARN_ON(1); |
307 | } |
308 | } |
309 | } |
310 | |
311 | static const struct reset_control_ops rst_ops = { |
312 | .assert = tegra_clk_rst_assert, |
313 | .deassert = tegra_clk_rst_deassert, |
314 | .reset = tegra_clk_rst_reset, |
315 | }; |
316 | |
317 | static struct reset_controller_dev rst_ctlr = { |
318 | .ops = &rst_ops, |
319 | .owner = THIS_MODULE, |
320 | .of_reset_n_cells = 1, |
321 | }; |
322 | |
323 | void __init tegra_add_of_provider(struct device_node *np, |
324 | void *clk_src_onecell_get) |
325 | { |
326 | int i; |
327 | |
328 | tegra_car_np = np; |
329 | |
330 | for (i = 0; i < clk_num; i++) { |
331 | if (IS_ERR(ptr: clks[i])) { |
332 | pr_err |
333 | ("Tegra clk %d: register failed with %ld\n" , |
334 | i, PTR_ERR(clks[i])); |
335 | } |
336 | if (!clks[i]) |
337 | clks[i] = ERR_PTR(error: -EINVAL); |
338 | } |
339 | |
340 | clk_data.clks = clks; |
341 | clk_data.clk_num = clk_num; |
342 | of_clk_add_provider(np, clk_src_get: clk_src_onecell_get, data: &clk_data); |
343 | |
344 | rst_ctlr.of_node = np; |
345 | rst_ctlr.nr_resets = periph_banks * 32 + num_special_reset; |
346 | reset_controller_register(rcdev: &rst_ctlr); |
347 | } |
348 | |
349 | void __init tegra_init_special_resets(unsigned int num, |
350 | int (*assert)(unsigned long), |
351 | int (*deassert)(unsigned long)) |
352 | { |
353 | num_special_reset = num; |
354 | special_reset_assert = assert; |
355 | special_reset_deassert = deassert; |
356 | } |
357 | |
358 | void tegra_register_devclks(struct tegra_devclk *dev_clks, int num) |
359 | { |
360 | int i; |
361 | |
362 | for (i = 0; i < num; i++, dev_clks++) |
363 | clk_register_clkdev(clks[dev_clks->dt_id], dev_clks->con_id, |
364 | dev_clks->dev_id); |
365 | |
366 | for (i = 0; i < clk_num; i++) { |
367 | if (!IS_ERR_OR_NULL(ptr: clks[i])) |
368 | clk_register_clkdev(clks[i], __clk_get_name(clk: clks[i]), |
369 | "tegra-clk-debug" ); |
370 | } |
371 | } |
372 | |
373 | struct clk ** __init tegra_lookup_dt_id(int clk_id, |
374 | struct tegra_clk *tegra_clk) |
375 | { |
376 | if (tegra_clk[clk_id].present) |
377 | return &clks[tegra_clk[clk_id].dt_id]; |
378 | else |
379 | return NULL; |
380 | } |
381 | |
382 | static struct device_node *tegra_clk_get_of_node(struct clk_hw *hw) |
383 | { |
384 | struct device_node *np; |
385 | char *node_name; |
386 | |
387 | node_name = kstrdup_and_replace(src: hw->init->name, old: '_', new: '-', GFP_KERNEL); |
388 | if (!node_name) |
389 | return NULL; |
390 | |
391 | for_each_child_of_node(tegra_car_np, np) { |
392 | if (!strcmp(np->name, node_name)) |
393 | break; |
394 | } |
395 | |
396 | kfree(objp: node_name); |
397 | |
398 | return np; |
399 | } |
400 | |
401 | struct clk *tegra_clk_dev_register(struct clk_hw *hw) |
402 | { |
403 | struct platform_device *pdev, *parent; |
404 | const char *dev_name = NULL; |
405 | struct device *dev = NULL; |
406 | struct device_node *np; |
407 | |
408 | np = tegra_clk_get_of_node(hw); |
409 | |
410 | if (!of_device_is_available(device: np)) |
411 | goto put_node; |
412 | |
413 | dev_name = kasprintf(GFP_KERNEL, fmt: "tegra_clk_%s" , hw->init->name); |
414 | if (!dev_name) |
415 | goto put_node; |
416 | |
417 | parent = of_find_device_by_node(np: tegra_car_np); |
418 | if (parent) { |
419 | pdev = of_platform_device_create(np, bus_id: dev_name, parent: &parent->dev); |
420 | put_device(dev: &parent->dev); |
421 | |
422 | if (!pdev) { |
423 | pr_err("%s: failed to create device for %pOF\n" , |
424 | __func__, np); |
425 | goto free_name; |
426 | } |
427 | |
428 | dev = &pdev->dev; |
429 | pm_runtime_enable(dev); |
430 | } else { |
431 | WARN(1, "failed to find device for %pOF\n" , tegra_car_np); |
432 | } |
433 | |
434 | free_name: |
435 | kfree(objp: dev_name); |
436 | put_node: |
437 | of_node_put(node: np); |
438 | |
439 | return clk_register(dev, hw); |
440 | } |
441 | |
442 | tegra_clk_apply_init_table_func tegra_clk_apply_init_table; |
443 | |
444 | static int __init tegra_clocks_apply_init_table(void) |
445 | { |
446 | if (!tegra_clk_apply_init_table) |
447 | return 0; |
448 | |
449 | tegra_clk_apply_init_table(); |
450 | |
451 | return 0; |
452 | } |
453 | arch_initcall(tegra_clocks_apply_init_table); |
454 | |